Annotation of 43BSD/ucb/ex/TODO, revision 1.1

1.1     ! root        1: From gbergman@UCBBRAHMS Mon Jul 25 16:21:43 1983
        !             2: Date: 25 Jul 83 16:16:52 PDT (Mon)
        !             3: From: gbergman@UCBBRAHMS (George Mark Bergman)
        !             4: Subject: Re:  editor bugs etc.
        !             5: Message-Id: <[email protected]>
        !             6: Received: by UCBBRAHMS.ARPA (3.342/3.7)
        !             7:        id AA22776; 25 Jul 83 16:16:52 PDT (Mon)
        !             8: Received: from UCBBRAHMS.ARPA by UCBERNIE.ARPA (3.336/3.7)
        !             9:        id AA13678; 25 Jul 83 16:21:17 PDT (Mon)
        !            10: To: mckusick@UCBERNIE
        !            11: Status: R
        !            12: 
        !            13: The following are (i) a short note from Mark Horton
        !            14: in reply to a note of mine saying I'd been keeping notes
        !            15: on editor bugs, had heard he had a new version, was
        !            16: interested in hearing about it and perhaps sending
        !            17: him notes on bugs not mentioned as corrected; (ii)
        !            18: a long letter from me in which I do list bugs, features
        !            19: I think would be desirable etc., (iii) an addendum I
        !            20: sent the next day, (iv) brief jottings not yet sent.
        !            21: 
        !            22: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
        !            23: >From [email protected] Thu Jul 21 12:31:55 1983
        !            24: 
        !            25: The new version of vi isn't very different to the user.
        !            26: The internals use terminfo instead of termcap, but the
        !            27: user interface isn't affected by this (except that it
        !            28: starts up faster).  The major new features are
        !            29:        set showmode
        !            30:                will cause an indication on the status line when
        !            31:                you are in input mode
        !            32:        vedit
        !            33:                is a new invocation of vi for novices
        !            34:        more function keys now work
        !            35:        function keys work in both command and input mode
        !            36: Of course, there are a few bug fixes too.
        !            37: 
        !            38: There is a binary in ~mark/bin/vi on ucbarpa.  It requires the
        !            39: /etc/term heirarchy (there is no file called /etc/terminfo) which
        !            40: was on ucbarpa once but might be gone now.  If you want to grab
        !            41: them from whereever they still exist, please feel free to try them.
        !            42:        Mark
        !            43: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
        !            44: Sent to Mark Horton  23/7/83, about 11AM
        !            45: 
        !            46: Dear Mark,
        !            47: 
        !            48:      Well, your note didn't say you wanted me to send my comments
        !            49: on editor bugs and suggestions, but you didn't say I shouldn't,
        !            50: so I decided to do so.  I've tried to organize it into some sort
        !            51: of sections.  I'd be interested to know which of the bugs mentioned
        !            52: here you have already found and corrected.  (I may soon find out for
        !            53: myself; the person in charge of this machine says he'll try to get a
        !            54: copy of version 3.9 from UCBARPA if they still have it, and get it
        !            55: running for me.  If you have any helpful information for him, he
        !            56: is robert@brahms, Robert Gross.)
        !            57:      Vedit sounds like a great idea.
        !            58:      I should mention that throughout this letter, I have
        !            59: avoided using actual control-characters, but faked them,
        !            60: e.g. used ^ and H to get the appearance of ^H, since files with
        !            61: real control-characters can be confusing when looked at in mail,
        !            62: more, etc.  But this means that if you want to try any commands I
        !            63: refer to that use them, you won't be able to yank and source them,
        !            64: unless you replace my fakes with real control characters.
        !            65:      The version I am using is 3.7.
        !            66: 
        !            67: 
        !            68: PROBLEMS WITH COUNTS
        !            69: 
        !            70:      Some  vi operations that logically ought to be able to take
        !            71: counts do not, while others misbehave with counts.  In this section,
        !            72: ``N'' will always denote a positive integer placed as a count before
        !            73: a vi operation.
        !            74:      The most gross case of misbehavior is that of N^B!
        !            75: The effect is to redraw the screen 23N-44 lines further advanced.
        !            76: (Probably the numbers depend on the screen-size of the terminal;
        !            77: this is on a Z19, using termcap h19u.)  When N=1, this does indeed
        !            78: move you a screenful backward, but for higher N it moves the window
        !            79: forward some amount!  Further, whatever controls are supposed to
        !            80: monitor whether the command would land one at an acceptable line-
        !            81: number seem to have a different idea of what it is doing:  If you
        !            82: aren't already familiar with these weird effects, try setting the
        !            83: cursor near the end of a file that is more than 4 screenfuls long,
        !            84: and hitting 3^B.  (You might then try an insert at the place you get
        !            85: to, and a :f^] .)
        !            86:      N/pattern/ would be useful, but is not allowed.
        !            87:      ND would be a natural synonym for dN$, by analogy with NC for cN$,
        !            88: but it doesn't work that way; it just ignores the N.
        !            89:      Finally, if N is precisely the number of lines
        !            90: from the current line to the end of the file,  N$  will still correctly
        !            91: carry one to the last character of the file, but cN$, NC, dN$ and yN$
        !            92: refuse to do anything!  (NY does work, not being a synonym for yN$.)
        !            93: The failure of NC is particularly annoying; often when I am composing
        !            94: something, I go back to somewhere in the middle of the next-to-
        !            95: last line, say, and want to rewrite the rest of the sentence;
        !            96: 2cc would kill not only the part I want to rewrite but also the OK
        !            97: beginning of the line, and 2C or 2c$ won't work.  I realize that I
        !            98: could get around this by keeping an empty line at the end of the file,
        !            99: but that should not be necessary.
        !           100: 
        !           101: 
        !           102: PROBLEMS REGARDING SOURCE, MACROS, MAPPINGS
        !           103:      These are enormously useful, but seem to have all kinds of hidden
        !           104: restrictions.
        !           105: 
        !           106:      The Appendix to the Ex Reference Manual, "List of Changes from
        !           107: Version 3.5 to Version 3.6" says ``A bug which prevented the source
        !           108: command from working...from visual has been fixed''.  It is true that
        !           109: one can now use  :so  from vi, but it still has a bug:  When
        !           110: the scriptfile invoked contains a global command
        !           111: and some other command(s) after it, everything after the first global
        !           112: command is ignored.  The same appears to be true of scripts in named
        !           113: buffers invoked from vi-bottom-line by  @x.
        !           114: 
        !           115:      (It is, perhaps, unexpected that one can invoke scripts with
        !           116: multiline commands using @x from vi's bottom-line at all, since such
        !           117: commands will not work if typed on vi's bottom line directly.
        !           118: A script like
        !           119:        s/$/a\
        !           120:        b
        !           121: invoked as @x will indeed work.  But strangely, if one tries to
        !           122: invoke from the regular mode of vi the script
        !           123:        :s/$/a\
        !           124:        b
        !           125: by putting it in buffer x and doing  @x, only the first line
        !           126: will take effect.)
        !           127:  
        !           128:      Another serious restriction is that the command ``vi'' appears to
        !           129: be ignored in sourced ex-scripts, and though the command Q in macros of
        !           130: various flavors in vi (mapped characters, map!ed characters that contain
        !           131: ``...^V^[...Q...'';  @x scripts) does take one into ex, any ex
        !           132: commands after it are ignored.
        !           133:  
        !           134:      I assume you are aware of whatever restrictions lead to the
        !           135: error-message ``Cannot yank inside global/macro'', since you must
        !           136: have written it, though ``inside'' seems to here have the peculiar
        !           137: meaning ``after a text-changing operation of the macro.''
        !           138:      The error-message ``Can't undo in global commands'' is more
        !           139: mysterious, since I get it when I have a global command after
        !           140: a text-changing command in an @x script (though not in a sourced file).
        !           141:      Anyway, the fewer such restrictions these operations were subject
        !           142: to, the more useful they would be!
        !           143: 
        !           144:      Although nested source commands are allowed (and I find them
        !           145: useful), they leave the editor in a ``noprompt'' state.  This
        !           146: can be gotten around by including ``se prompt'' as a line in the
        !           147: outermost scriptfile, but I would hope the problem causing it could
        !           148: be cured.
        !           149: 
        !           150:      When one tries to ``:unmap!'' a ``:map!'' command whose
        !           151: right-hand-side begins with ^H (entered as ^V^H, of course), one
        !           152: gets the message ``That macro wasn't mapped''.  (One can get around
        !           153: this by using :unmap! ^V[character].)
        !           154: 
        !           155:      Certain termcaps apparently produce automatic mappings, which
        !           156: unfortunately may interfere with useful vi commands.  In particular,
        !           157: on a tvi, ^L gets mapped to a movement command, which makes it
        !           158: unavailable for redrawing the screen, unless unmapped.
        !           159: 
        !           160: 
        !           161: PROBLEMS WITH DIAGNOSTICS
        !           162: 
        !           163: "Hit return to continue" -- It took me a long time to realize that
        !           164: when I got this diagnostic there was an alternative to hitting
        !           165: return.  I suggest it be reworded
        !           166:        "Hit Return or :"
        !           167: However, the behavior of the editor when this diagnostic is given
        !           168: seems to be inconsistent.  In particular, when the last of a serious
        !           169: of commands is
        !           170:        :e otherfile
        !           171: and I get "Hit return to continue", then hitting : usually
        !           172: has no different effect from hitting return (or any other
        !           173: key), namely the screen is redrawn; yet I think that sometimes
        !           174: in this situation it has brought me directly to the bottom line
        !           175: as desired.  Very confusing.
        !           176:      Would it be possible to have other alternatives than : and return
        !           177: available, such as /pattern ?  Or, more simply, when one would presently
        !           178: be given the diagnostic "Hit return to continue", why not just put the
        !           179: editor into the state it would have if one then hit :, since one would
        !           180: then still have the option of hitting return and getting into vi
        !           181: proper, but it would not require the extra keystroke : to
        !           182: begin a bottom-line command, nor would one go through the frequent
        !           183: frustrating experience of absentmindedly starting to write a
        !           184: bottom-line command, or a pattern-search, and then having to wait
        !           185: while the screen was redrawn because one had hit a key other than :.
        !           186: 
        !           187: "Using open mode"
        !           188: Again, it took me a long time to learn that when I tried to enter
        !           189: vi and got this diagnostic, it meant that the system had somehow
        !           190: lost the termcap for the terminal I was on, and that I would have
        !           191: to do something to get the correct termcap into the environment.
        !           192: Till I realized this, I generally ended up either struggling along
        !           193: frustrated in open mode, or logging out and logging back in.  I suggest
        !           194: that when someone calls for vi and the termcap is not appropriate,
        !           195: the editor should not be invoked in any form, but instead, a message
        !           196: be given such as:
        !           197:      ``Your environment does not show a termcap entry permitting
        !           198: the use of the visual editor.  If you are working on a terminal not
        !           199: supporting vi (in particular, a device with no addressable cursor),
        !           200: you may enter one of the other modes of the editor with the command
        !           201: "open filename" or "ex filename".  If you are working on a terminal
        !           202: that should support vi, your environment entries are incorrect and
        !           203: should be corrected.  They presently show:
        !           204:      TERM=....
        !           205:      TERMCAP=....
        !           206: If you know the correct name or abbreviation for your terminal-
        !           207: type, type it at the end of the next line; if not hit return:
        !           208:      % setenv TERM ''
        !           209:      If the user typed an acceptable terminal-name, the message would
        !           210: continue, telling how to get the appropriate termcap.  If the user
        !           211: instead typed return, the message would ask him or her to type the
        !           212: name of the manufacturer shown on the terminal, not
        !           213: worrying about upper/lower-case distinctions, and a list of possible
        !           214: terminal names and abbreviations would be given... .  This whole
        !           215: program would not be part of the editor, so there would
        !           216: be no problem of space within the existing crowded confines of
        !           217: the editor code.
        !           218: 
        !           219: "No such file or directory" -- I think there should be a distinction
        !           220: between these two cases, because of the important distinction in the
        !           221: consequences when the user tries to quit the editor:
        !           222: If the directory exists, the file is created, but
        !           223: if not, the results are more complicated -- I seem to recall on one
        !           224: occasion simply losing what I had written on my second try
        !           225: at quitting; though I just now did an experiment and this time
        !           226: repeated ZZ's and :x's simply gave repeated error messages.
        !           227: 
        !           228: "File already exists..." -- The ``List of changes from 3.5 to 3.6'' says
        !           229: ``If you get I/O errors, the file is considered "not edited"... .''
        !           230: I presume that this correction is somehow the cause of the fact that
        !           231: I frequently get the above message when trying to leave the editor
        !           232: on a machine with version 3.7, and have to use
        !           233:       :w! %|q
        !           234: to exit.  But I've never seen any evidence that there were I/O errors;
        !           235: it mainly seems to happen when I've written some lines to another
        !           236: file in the process of editing.  So the criteria the editor is using
        !           237: to decide when there have been ``I/O errors'' should be rechecked.
        !           238: 
        !           239: "no such command from open/visual" -- This confused me in my first
        !           240: few days of using the editor, when I didn't understand that one
        !           241: couldn't use i and a (in either their vi or ex senses) from the bottom
        !           242: line of vi.  A message "i -- no such command from open/visual"
        !           243: was perplexing because I knew that "i" was indeed a vi command.
        !           244: Perhaps it should say  "no such command from open/visual bottom line".
        !           245: 
        !           246: MISCELLANEOUS PROBLEMS
        !           247: 
        !           248:      In ex search and replacement patterns, \\ is supposed to represent
        !           249: a real \-character, but something goes wrong when this occurs
        !           250: at the end of a global command.  E.g., though
        !           251:      :s/^/\\
        !           252: works OK (in vi or ex), the variant
        !           253:      :.g/^/s//\\
        !           254: definitely does not.  In vi it turns everything off, in ex it seems to
        !           255: behave as though there were just a single \, and in a scriptfile,
        !           256: it -- does something still different, which you can discover if you
        !           257: don't know!
        !           258: 
        !           259: The Ex Reference Manual says, ``For sanity with use from within
        !           260: visual mode, ex ignores a ":" preceding any command.''  But it
        !           261: ignores it in the wrong place! -- not at the beginning of the
        !           262: command line, but just before the command letter itself.  I.e.,
        !           263: it accepts 1,3:s/^/     /, but not :1,3s/^/    /.
        !           264: 
        !           265: SUGGESTIONS FOR MINOR ADDED CAPABILITIES
        !           266: 
        !           267:    In a multiline substitute command with the "c" option, when
        !           268: each line is displayed one has three choices: y, n or break.  There
        !           269: are some further options that would be useful.  One would be "p" --
        !           270: at present, "p" can only be included on the command line, which
        !           271: means that one has a choice between seeing the result of every
        !           272: substitution or none.  In practice, one would generally like to see
        !           273: the results of the first few cases to make sure that the command one has
        !           274: written does what one meant it to, and maybe a few tricky cases that
        !           275: come up; but not every case!   Another might be "u" -- to undo the last
        !           276: case for which one gave a "y".  Still another might be an option that
        !           277: would mean ``undo the "c" option -- I see that the substitute command
        !           278: is doing what I wanted, go ahead and finish it without me.''
        !           279:     In a command  g/pattern/p,  the pattern in question is occasionally
        !           280: such that it takes a while to figure out where on the line it occurs.
        !           281: For this purpose, an option that ``pointed out'' the instance of the
        !           282: pattern, in the same manner that the pattern to be replaced is pointed
        !           283: out in substitute command with option c, would be desirable.
        !           284:     When  g/pattern/p  gives more than a screenful of lines, it would
        !           285: be nice to have it piped through the equivalent of ``more''.
        !           286: 
        !           287:     ex has the command line option "-", which ``is useful in processing
        !           288: editor scripts''.  But if one wants to use a script in the course of
        !           289: an otherwise interactive editing session, it would be desirable to have
        !           290: a corresponding resettable option ``:se -'' (or ``:se nofb'').
        !           291: 
        !           292:      In strings in pattern-searches, it would be useful to have
        !           293: ^ and $ retain their ``magic'', so that /x[a$]/ could
        !           294: search for all occurrences of  x  before an  a  or a newline.
        !           295: (Of course, one would then have to decide whether  /x[^y]/ should
        !           296: include the case of  x  followed by a newline or not.)
        !           297: 
        !           298:     Just as ex allows the command :vi, so I think that vi should
        !           299: have some bottom-line command equivalent to the regular-mode
        !           300: command  Q.  When one has done some text-changing bottom-line
        !           301: commands, and realizes one wants to go into ex, it can be time-
        !           302: consuming to hit return and then Q, and wait for the screen to be
        !           303: redrawn for vi before one gets the ex prompt.
        !           304: 
        !           305:      The option of putting several commands on one line, separated
        !           306: by, "|" is particularly useful in the vi bottom-line mode, because
        !           307: it avoids having the screen redrawn several times.  It would be
        !           308: useful to be able sometimes do the same thing with non-bottom-line
        !           309: commands, e.g. in editing a troff file at a low baud rate on a dumb
        !           310: terminal one might like to be able to do  i\fI^]3Ea\fR^]  without
        !           311: watching the line get redrawn twice.  Perhaps some key that would
        !           312: cause any sequence of commands to be ``held'' until some complementary
        !           313: key was hit would be useful.
        !           314:      It would also be desirable to have a sequence of commands that had
        !           315: been given in this way available as one unit to be repeated by ``.'',
        !           316: if desired.
        !           317: 
        !           318:      The parenthesis-matching facility with % might be extended
        !           319: to match ` with ' and <  with  >.
        !           320: 
        !           321:      I will mention one facility that I discovered by surprize is
        !           322: possessed by  ed  but not  ex  --  sequences such as  \1  can be used
        !           323: within  ed  search-patterns.  E.g. (for the most trivial case)
        !           324:      /\(.\)\1/
        !           325: will search for doubled letters.
        !           326: 
        !           327: 
        !           328: DEBATABLE SUGGESTIONS
        !           329:      I will mention here some possible changes which have the
        !           330: difficulty that they would change the meaning of existing commands,
        !           331: so that it could be argued that the disadvantage of users having
        !           332: to change their habits might outweigh the advantages.
        !           333: 
        !           334:      First, one might try to resolve, one way or another, the
        !           335: contradiction between the count arguments taken by the join commands
        !           336: in  vi and  ex:  In ex, jN joins N+1 lines; in vi, NJ joins N lines
        !           337: (except if N=1).
        !           338: 
        !           339:      Second, the movement commands  tx  and  Tx  of vi (x any character)
        !           340: seem poorly defined.  Just as fx will ignore the character on which
        !           341: the cursor is presently sitting, even if it is an  x,  and move to the
        !           342: next occurrence, so I would think that  tx  should ignore the character
        !           343: immediately after the cursor, and  Tx  the character immediately before
        !           344: the cursor.  The point is that when one does  Nfx,  and finds that one
        !           345: had failed to count one occurrence of  x  and fallen short of where one
        !           346: wanted to go, one can hit  ;  and get there.  Likewise, on doing  Ntx
        !           347: and finding one has fallen short, one should be able to hit  ;  and get
        !           348: to the the next occurrence; but at present, hitting  ;  leaves
        !           349: the cursor in the same position; one must hit  ``2;''  to get any
        !           350: further.  In effect,  Ntx  is presently defined as  Nfxh;  I am
        !           351: suggesting that it be defined as  lNfxh.
        !           352: 
        !           353:      The sequences  cw, dw  and  yw  are presently violations of the
        !           354: principle that  c[movement],  d[movement]  and  y[movement]  change,
        !           355: delete, or yank everything from the current cursor position through
        !           356: the endpoint of the movement command.  cw does what one would expect of
        !           357: ce (in fact, they seem to be synonyms), while there is no way to get
        !           358: the effect which  cw  would have if it were treated ``consistently''.
        !           359: (E.g., if I have a line beginning  ``And if'', and I want to change it
        !           360: to ``If'', I cannot just put the cursor on the A and hit  cwI^].)  dw
        !           361: and  yw  delete up to the character immediately before the point to
        !           362: which ``w'' would take the cursor.  I would have to agree that this
        !           363: behavior of dw and  yw  is more useful than that which a literal
        !           364: interpretation of the movement rule would lead to; but perhaps it
        !           365: would become still more useful if when applied to the last word on
        !           366: a line, it deleted or yanked the space immediately before the word
        !           367: along with the word... .  On the other hand, one could argue for
        !           368: making a distinction between  cw  and  ce.
        !           369: 
        !           370:      Though I see the motivation for the above definitions,
        !           371: I see no sensible reason why  Y  should be equivalent to  yy,  when
        !           372: C  and  D  are equivalent to  c$  and  d$.  I would vote for changing
        !           373: Y  to mean  y$.
        !           374: 
        !           375: RADICAL SUGGESTIONS
        !           376: 
        !           377:      Is there any reason for maintaining the distinction between
        !           378: the ``:'' state of vi, and  ex  itself?  At present, there are
        !           379: relative advantages that lead one to choose to go into one or the
        !           380: other for a given operation:  From the vi-: state, it is easier
        !           381: to return to the regular vi state; from ex, one has a more powerful
        !           382: range of commands; and it is easier to give a series of commands
        !           383: because each carriage-return gives one a new prompt.  My suggestion
        !           384: is that from vi, ``:'' should carry you directly to ex, and when you
        !           385: are in ex, carriage-return (^M) after a command should give you a new
        !           386: prompt, while ^] should put you into vi.  Conceivably, things might be
        !           387: simplified even further, and carriage return rather than : could
        !           388: be the key that would carry one from the regular mode of vi into ex:
        !           389: 
        !           390:                         .-------.      .-------.
        !           391:        .-------. a,i... | basic |  ^M  |       |
        !           392:        |  vi   |<------ |       |----->|  ex   |<---.
        !           393:        | insert|        |   vi  |      |       |    |^M
        !           394:        |  mode | ------>|       |<-----| mode  | ---'
        !           395:        `-------'  ^]    |  mode |   ^] |       |
        !           396:                         `-------'      `-------'
        !           397: 
        !           398: (Of course, ^M presently has a meaning in vi, but
        !           399: it has a synonym +.)  Clearly, there would also be no need for a
        !           400: special "Hit return to continue" state.
        !           401:      I have not distinguished vi and open in the above diagram.
        !           402: My idea here is that ^] would actually return you to either vi
        !           403: or open, whichever you had last been in, and that to switch
        !           404: to the other, you could enter ex and type vi^] or o^] respectively.
        !           405: (Or you could type  vi^M, respectively o^M, and further ex commands,
        !           406: and the mode would be saved for the next time you hit a ^].)  Or
        !           407: alternatively, these could be made settable options: se visual
        !           408: respectively se novisual.
        !           409:      Having gotten used to the editor as it now exists, I admit that
        !           410: I feel uneasy about the above idea -- the sense of knowing that
        !           411: I am ``still in vi'' when I hit :, and not that ``other land'' of ex, 
        !           412: represents a kind of of orientation that it is disconcerting
        !           413: to abandon.  But I can't see any logical disadvantage in making
        !           414: such a change.  Can you?  Certainly, there would be things that
        !           415: would have to be thought out, such as what happens to bottom-line
        !           416: vi pattern-searches.  My thought would be that ``/'' from vi should
        !           417: give :/ (i.e., put one in ex at the start of a pattern-search),
        !           418: and ^] after a pattern-search should put one into vi at the appropriate
        !           419: character on the line, in contrast to ^M after a pattern search,
        !           420: which would leave one in ex at the appropriate line.  In general,
        !           421: I think such changes would lead to greater simplicity and learnability
        !           422: of the editor.
        !           423:      I would also hope that excursions between vi and ex and back
        !           424: could be allowed in scriptfiles.  It might also be desirable for
        !           425: ex to have, in addition to a concept of ``current line'', one of
        !           426: ``current cursor position''... .
        !           427: 
        !           428:      Well, on to another subject.  One of the inconveniences I
        !           429: found very vexing when first learning to use the editor was that
        !           430: when in either vi insert mode, or ex/vi-bottom-line, it was very hard
        !           431: to edit what I was doing.  Within insert mode the only ``editing''
        !           432: I could do, without escaping, was with the three operations ^H,
        !           433: ^W and the kill character.  And on a slow line with a dumb terminal,
        !           434: escaping to make changes could be very time-consuming because large
        !           435: parts of the screen would insist on being redrawn.  Perhaps some
        !           436: other control-character could serve as
        !           437: a modified escape, that allowed one to edit what one had entered
        !           438: in the current insertion without having everything below it redrawn,
        !           439: and then return to it.  Obviously, if carried to its logical
        !           440: limit this idea could lead to ridiculous nests of
        !           441: editing operations; but there would be no need to carry it to its
        !           442: logical limit.
        !           443:      Anyway, the problem of editing ex-style commands
        !           444: was even worse, because there was no way to ``escape and
        !           445: revise''.  I eventually learned enough to realize that the solution
        !           446: was to edit complicated commands in another file and source it.
        !           447: But it is sometimes very useful to have the text on which the
        !           448: commands are to act in front of you when composing them (e.g., you can
        !           449: yank and modify various pieces), which led to the variant of writing
        !           450: command lines within the file I was editing, and then writing
        !           451: those lines into another file and sourcing that, without ever leaving
        !           452: the current file.  But this is distracting to deal with
        !           453: when concentrating on the editing task itself, which led me
        !           454: to divise a scriptfile which would handle the writing-to-another-file-
        !           455: and-sourcing for me.  Or actually, several such files:  One for
        !           456: single-line commands to be used essentially once; one for single-line
        !           457: commands that I would want to use on the same file during various
        !           458: editing sessions, and so would want to keep available in that
        !           459: file, and one for multi-line commands (to be used once).  When
        !           460: I first got the idea, I thought one scriptfile would be enough, and
        !           461: I would call it ``do'', so that the command to execute a script I
        !           462: had written in a file I was editing would be ``:so do''.  The
        !           463: file it would write to and source would be ``do.again'', so that
        !           464: if I wanted to reuse it, I could ``:so do.again''.  When I realized
        !           465: the need for several versions, ``do'' became a directory.  Here,
        !           466: for your amusement, are the three files.  (Re the lines ``se prompt'',
        !           467: cf. my comment on that under PROBLEMS WITH SOURCE etc.):
        !           468: 
        !           469:   do/1  (for 1-time use of 1-line commands)
        !           470:        .w! ~/do/again
        !           471:        d
        !           472:        so #
        !           473:        se prompt
        !           474: 
        !           475:   do/1+  (like above, without deleting the command)
        !           476:        .w! ~/do/again
        !           477:        so #
        !           478:        se prompt
        !           479: 
        !           480:   do/:  (to use this, write a multi-line command script, put : at
        !           481:   the beginning of the first line, put the cursor on the last
        !           482:   line of the script, and then source the following:)
        !           483:        ?^:?s/:/
        !           484:        ,''w! ~/do/again
        !           485:        ,''d
        !           486:        so #
        !           487:        se prompt
        !           488: 
        !           489: (I also created another version to use in case the script had
        !           490: to have an internal line beginning with ``:'', so that this couldn't
        !           491: unambiguously mark the beginning of the script.  This used
        !           492: a line which explicitly specified the address-range of the script.
        !           493: But I have never had a need for it, so I will not bother you with it.)
        !           494:     Finally, having gotten an account on a machine with a version 3
        !           495: editor recently, I have divised still another way of doing this.  I
        !           496: have put in my EXINIT the command
        !           497: 
        !           498:        'map ^A "ayy:@a^M'
        !           499: 
        !           500: and now, gratifyingly, the single stroke ^A has essentially the effect
        !           501: of ``:so do/1+''  -- except for the restrictions to which vi ``map''
        !           502: commands are subject.  But I've only been using this for a
        !           503: couple of weeks; so I have yet to learn how chafing those restrictions
        !           504: will or won't be.
        !           505:      Anyway, it might be worth thinking about whether some of these
        !           506: things that I've done with macros should be incorporated in some form
        !           507: into the editor itself; or else whether these macros might be written
        !           508: up in the documentation (or some tutorials) on the editor.
        !           509: 
        !           510:      Next subject: Complicated pattern-searches in long files
        !           511: can be time-consuming.  I have seen the point mentioned
        !           512: that if a pattern-description can be begun with "^",
        !           513: this can speed up the search -- since the pattern-comparisons need
        !           514: only be begun at beginnings of lines.  In some cases, this might
        !           515: not be possible, but the user might be aware of some other
        !           516: character or character-sequence in the search-pattern
        !           517: that will occur relatively rarely in the file.  In such cases it would
        !           518: be desirable if the user could specify one spot from which the pattern
        !           519: search should start, working forward and backward from there, to
        !           520: minimize false starts.  E.g., if for some reason one wants to
        !           521: delete every word containing the letter m, the script
        !           522:        %s/[^ ]*m[^ ]*//
        !           523: would become much less time-consuming if one could mark the point
        !           524: at which to begin, say writing
        !           525:        %s/[^ ]*\!m[^ ]*//
        !           526: so as to instruct the editor to search for m's, and each time
        !           527: one was found, to find the longest possible strings of non-space
        !           528: characters before and after it, and delete these.   (This is a silly
        !           529: example, but I think the idea is clear.)
        !           530: 
        !           531:      Something that I've seriously felt the need for is the
        !           532: capability of searching for lines that satisfy more than one
        !           533: condition.  If one just wants to locate such lines, one can
        !           534: of course leave the editor and do a pipeline of two or
        !           535: more greps; but it would be nice to be able to perform global
        !           536: commands on such lines.
        !           537: 
        !           538:     Finally, any possibility of introducing the capability of searching
        !           539: for patterns including embedded newlines, a la sed?  Multiple windows,
        !           540: a la emacs?
        !           541: 
        !           542: ADDENDA
        !           543:      I logged in this morning on an adm3a at 300 baud to go over this
        !           544: letter once more before sending it, and ran into another bug!  I had
        !           545: done 15^D to get a large scroll despite the low speed, and at one point
        !           546: I saw a line with a typo scrolling up.  So I noted its line-number, 402
        !           547: and without waiting for the screen to stop moving typed something like
        !           548: 402Gfsrd.  What happened was that the change was made on line 407 rather
        !           549: than 402 -- presumably the cursor was sent to where 402 had been when
        !           550: the command was received... .
        !           551:      Editing this letter this morning reminded me of another feature I
        !           552: have thought would be desirable for editing on dumb terminals at low
        !           553: speeds:  An option that would cause lines read from a file or typed
        !           554: in at the bottom of the screen to appear double spaced, with @ signs
        !           555: @
        !           556: between them, such as one gets when one deletes a line on such a
        !           557: @
        !           558: terminal.  (I have faked this effect here, though the fake will not be
        !           559: @
        !           560: very successful if you have  se nu  or  se list  on.)  The point is that
        !           561: @
        !           562: editing operations that presently cause painfully slow screen-redrawings
        !           563: would simply put material in in place of these fillers -- as happens
        !           564: now when one is lucky enough to be adding material just above a place
        !           565: where material was previously deleted.
        !           566: 
        !           567:                -  *  -  *  -  *  -  *  -  *  -
        !           568: 
        !           569:     I hope you've found some things of interest in this hodgepodge.
        !           570: 
        !           571:                                Yours,
        !           572:                                George (gbergman@brahms)
        !           573: 
        !           574: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
        !           575: 23/7/83, about 8PM
        !           576: 
        !           577:      Maybe thinking about the editor while writing my previous
        !           578: ``note'' to you has made me more conscious of these things,
        !           579: but for some reason, I've discovered several more peculiarities of
        !           580: the the Version 3.7 editor today!
        !           581: 
        !           582:      First, the abbreviation feature has a strange bug (feature?)
        !           583: involving the backslash:  If some string X is the abbreviation
        !           584: for a string Y, and if X is typed (following a space etc)
        !           585: immediately followed by a \ and another character c, the
        !           586: result is not Y\c by cY\.  The case where I discovered this
        !           587: was a doubly complicated one: I had an abbreviation of
        !           588: the form
        !           589:        :ab x x\yZ
        !           590: where x and  y  were characters and Z was a string of characters.  
        !           591: So when I typed  x,  it presumably first expanded it as x\yZ,
        !           592: then performed the transformation I just described on the x\y
        !           593: turning it into  yx\yZ\, and thus giving the result yx\yZ\Z.
        !           594: This turns out to be one of the cases that can't be unmapped
        !           595: without doing :una ^Vx.  Further, I just tried a similar case
        !           596: with x replaced by a string of more than one character
        !           597: (namely, :ab if if\pq)  and I find I can't unmap that at all.
        !           598:      I also find that an abbreviated string containing | (which
        !           599: must be inserted using ^V|, of course) is difficult to unmap.
        !           600: 
        !           601:      Second, some peculiarities about where the cursor ends
        !           602: up after a yank.  If the yank involved a forward movement,
        !           603: the cursor stays where it is, which is the beginning
        !           604: of the yanked segment.  If the yank involves a backwards
        !           605: movement, the place where the cursor originally was is not
        !           606: the same as the beginning of the yanked segment, and there
        !           607: seems to be some confusion as to which principle is followed:
        !           608: y- or yk moves the cursor up, while yb leaves it fixed.
        !           609: Unfortunately, there is a snake in the grass with yb: If
        !           610: you hit p after it, the yanked word will not appear after
        !           611: the position where the cursor has remained, but
        !           612: after the position to which it would have gone if it had moved
        !           613: to the beginning of the yanked segment!  Likewise if you
        !           614: you hit an x... .
        !           615:      (You have no idea how much trouble I'm
        !           616: having with those "if"'s.  Of course, I could quit the editor
        !           617: and come back in, and I would lose that crazy abbreviation
        !           618: that way.)
        !           619: 
        !           620:      I also notice that if the cursor is at the end of a word
        !           621: or between words, 2e behaves the same as e!
        !           622: 
        !           623:      Finally, I note that d^, when the cursor is before the first
        !           624: nonwhite character, is another exception to the principle that
        !           625: d[motion] deletes everything through the endpoint of [motion].
        !           626: Similarly with c^ and y^.
        !           627: 
        !           628: - *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *- *
        !           629: discovered next day (not yet sent):
        !           630: 
        !           631: error with yb does not just concern p and x: any command is
        !           632: executed as though cursor is at destination of backward in-line
        !           633: yank.
        !           634: 
        !           635: N^B does not work consistently?  (Not on a medium-length file in Kim)
        !           636: 
        !           637: Can get endless-loop mapping if abbreviation forms word within
        !           638: abbreviated.  E.g. :ab x ( x )
        !           639: ``word'' must be delimited on left by space, tab,
        !           640: newline, start-of-insert; on right by any punctuation.  Why
        !           641: special ``no tail recursion'' rule?
        !           642:      Things like that ``if'' abbreviation can be undone using
        !           643: :una i^Vf!
        !           644: 
        !           645: Mention desirability of Np
        !           646: 
        !           647: copies sent to ralph@ucbarpa, lindahl@topaz 25/7/83
        !           648: 
        !           649: From gbergman@UCBCARTAN Mon Aug  1 14:19:27 1983
        !           650: Date: 1 Aug 83 14:14:06 PDT (Mon)
        !           651: From: gbergman@UCBCARTAN (George Mark Bergman)
        !           652: Subject: Re:  editor
        !           653: Message-Id: <[email protected]>
        !           654: Received: by UCBCARTAN.ARPA (3.342/3.7)
        !           655:        id AA00627; 1 Aug 83 14:14:06 PDT (Mon)
        !           656: Received: from UCBCARTAN.ARPA by UCBERNIE.ARPA (3.336/3.7)
        !           657:        id AA19324; 1 Aug 83 14:19:12 PDT (Mon)
        !           658: To: mckusick@UCBERNIE
        !           659: Status: R
        !           660: 
        !           661: Here's Mark Horton's reply to my letter on bugs
        !           662: 
        !           663: >From [email protected] Thu Jul 28 14:38:55 1983
        !           664: 
        !           665: Sorry this has taken so long, but your note was too long to digest
        !           666: in the cracks between the other stuff I do.  Anyway, you've clearly
        !           667: put a great deal of thought into this, and I appreciate your input.
        !           668: I'll reply individually to your thoughts, and keep them on file
        !           669: for use (someday) when vi gets rewritten.  Some of them are just
        !           670: plain bugs that ought to be fixed soon anyway.
        !           671: 
        !           672:        PROBLEMS WITH COUNTS
        !           673: 
        !           674:             The most gross case of misbehavior is that of N^B!
        !           675:        The effect is to redraw the screen 23N-44 lines further advanced.
        !           676:        (Probably the numbers depend on the screen-size of the terminal;
        !           677:        this is on a Z19, using termcap h19u.)  When N=1, this does indeed
        !           678:        move you a screenful backward, but for higher N it moves the window
        !           679:        forward some amount!  Further, whatever controls are supposed to
        !           680:        monitor whether the command would land one at an acceptable line-
        !           681:        number seem to have a different idea of what it is doing:  If you
        !           682:        aren't already familiar with these weird effects, try setting the
        !           683:        cursor near the end of a file that is more than 4 screenfuls long,
        !           684:        and hitting 3^B.  (You might then try an insert at the place you get
        !           685:        to, and a :f^] .)
        !           686: This is a known bug, and was fixed in 3.8.  The count is supposed to subtract
        !           687: (LINES-1)*N from the line number, but there's + that should be a -, so it
        !           688: goes forward instead.  The check is correct, so it's possible to go off
        !           689: the end of the buffer.
        !           690:             N/pattern/ would be useful, but is not allowed.
        !           691: N/pattern/ resets the window size (silly but true) to N.
        !           692:             ND would be a natural synonym for dN$, by analogy with NC for cN$,
        !           693:        but it doesn't work that way; it just ignores the N.
        !           694:             Finally, if N is precisely the number of lines
        !           695:        from the current line to the end of the file,  N$  will still correctly
        !           696:        carry one to the last character of the file, but cN$, NC, dN$ and yN$
        !           697:        refuse to do anything!  (NY does work, not being a synonym for yN$.)
        !           698:        The failure of NC is particularly annoying; often when I am composing
        !           699:        something, I go back to somewhere in the middle of the next-to-
        !           700:        last line, say, and want to rewrite the rest of the sentence;
        !           701:        2cc would kill not only the part I want to rewrite but also the OK
        !           702:        beginning of the line, and 2C or 2c$ won't work.  I realize that I
        !           703:        could get around this by keeping an empty line at the end of the file,
        !           704:        but that should not be necessary.
        !           705: While you're making valid observations here, are you aware that you can delete
        !           706: the current sentence with d} ?  I think that's what you really want.
        !           707: 
        !           708: 
        !           709:        PROBLEMS REGARDING SOURCE, MACROS, MAPPINGS
        !           710:             These are enormously useful, but seem to have all kinds of hidden
        !           711:        restrictions.
        !           712: 
        !           713:             The Appendix to the Ex Reference Manual, "List of Changes from
        !           714:        Version 3.5 to Version 3.6" says ``A bug which prevented the source
        !           715:        command from working...from visual has been fixed''.  It is true that
        !           716:        one can now use  :so  from vi, but it still has a bug:  When
        !           717:        the scriptfile invoked contains a global command
        !           718:        and some other command(s) after it, everything after the first global
        !           719:        command is ignored.  The same appears to be true of scripts in named
        !           720:        buffers invoked from vi-bottom-line by  @x.
        !           721: Sounds like a bug.
        !           722: 
        !           723:             (It is, perhaps, unexpected that one can invoke scripts with
        !           724:        multiline commands using @x from vi's bottom-line at all, since such
        !           725:        commands will not work if typed on vi's bottom line directly.
        !           726:        A script like
        !           727:                s/$/a\
        !           728:                b
        !           729:        invoked as @x will indeed work.  But strangely, if one tries to
        !           730:        invoke from the regular mode of vi the script
        !           731:                :s/$/a\
        !           732:                b
        !           733:        by putting it in buffer x and doing  @x, only the first line
        !           734:        will take effect.)
        !           735: In 3.7 (or 3.8, I'm not sure), you can say
        !           736:        :s/$/a^V^Mb
        !           737: to get a newline on the RHS.  Of course, this doesn't mean there isn't
        !           738: a bug in scripts.
        !           739:         
        !           740:             Another serious restriction is that the command ``vi'' appears to
        !           741:        be ignored in sourced ex-scripts, and though the command Q in macros of
        !           742:        various flavors in vi (mapped characters, map!ed characters that contain
        !           743:        ``...^V^[...Q...'';  @x scripts) does take one into ex, any ex
        !           744:        commands after it are ignored.
        !           745: The internals of getting a character from the tty are completely different
        !           746: in ex and vi.  Pushing input for one doesn't affect the other.  So there
        !           747: isn't much hope of changing this situation.
        !           748:         
        !           749:             I assume you are aware of whatever restrictions lead to the
        !           750:        error-message ``Cannot yank inside global/macro'', since you must
        !           751:        have written it, though ``inside'' seems to here have the peculiar
        !           752:        meaning ``after a text-changing operation of the macro.''
        !           753:             The error-message ``Can't undo in global commands'' is more
        !           754:        mysterious, since I get it when I have a global command after
        !           755:        a text-changing command in an @x script (though not in a sourced file).
        !           756:             Anyway, the fewer such restrictions these operations were subject
        !           757:        to, the more useful they would be!
        !           758: It's the way undo is done - the text for undo is saved in the "last deleted"
        !           759: buffer, and yank puts text there too.  Couple this with the fact that globals
        !           760: and macros can be undone as a unit (they save their state before the first change)
        !           761: and you'll see that the two notions can't coexist.  Of course, you can always
        !           762: yank into a named buffer, even inside a macro.
        !           763: 
        !           764:             Although nested source commands are allowed (and I find them
        !           765:        useful), they leave the editor in a ``noprompt'' state.  This
        !           766:        can be gotten around by including ``se prompt'' as a line in the
        !           767:        outermost scriptfile, but I would hope the problem causing it could
        !           768:        be cured.
        !           769: Bug, I guess.
        !           770: 
        !           771:             When one tries to ``:unmap!'' a ``:map!'' command whose
        !           772:        right-hand-side begins with ^H (entered as ^V^H, of course), one
        !           773:        gets the message ``That macro wasn't mapped''.  (One can get around
        !           774:        this by using :unmap! ^V[character].)
        !           775: Bug, I guess.
        !           776: 
        !           777:             Certain termcaps apparently produce automatic mappings, which
        !           778:        unfortunately may interfere with useful vi commands.  In particular,
        !           779:        on a tvi, ^L gets mapped to a movement command, which makes it
        !           780:        unavailable for redrawing the screen, unless unmapped.
        !           781: Well, there's no way for vi to tell the difference between ^L that the
        !           782: user typed as ^L and ^L that the user typed as right arrow.  However, there
        !           783: are a number of terminals that are upward compatible with the adm3a and use
        !           784: ^L for right arrow.  Vi has a special case for these built in - if the
        !           785: terminal has insert/delete line, and ^L is right arrow, then ^R will redraw
        !           786: the screen.
        !           787: 
        !           788: 
        !           789:        PROBLEMS WITH DIAGNOSTICS
        !           790: 
        !           791:        "Hit return to continue" -- It took me a long time to realize that
        !           792:        when I got this diagnostic there was an alternative to hitting
        !           793:        return.  I suggest it be reworded
        !           794:                "Hit Return or :"
        !           795:        However, the behavior of the editor when this diagnostic is given
        !           796:        seems to be inconsistent.  In particular, when the last of a serious
        !           797:        of commands is
        !           798:                :e otherfile
        !           799:        and I get "Hit return to continue", then hitting : usually
        !           800:        has no different effect from hitting return (or any other
        !           801:        key), namely the screen is redrawn; yet I think that sometimes
        !           802:        in this situation it has brought me directly to the bottom line
        !           803:        as desired.  Very confusing.
        !           804:             Would it be possible to have other alternatives than : and return
        !           805:        available, such as /pattern ?  Or, more simply, when one would presently
        !           806:        be given the diagnostic "Hit return to continue", why not just put the
        !           807:        editor into the state it would have if one then hit :, since one would
        !           808:        then still have the option of hitting return and getting into vi
        !           809:        proper, but it would not require the extra keystroke : to
        !           810:        begin a bottom-line command, nor would one go through the frequent
        !           811:        frustrating experience of absentmindedly starting to write a
        !           812:        bottom-line command, or a pattern-search, and then having to wait
        !           813:        while the screen was redrawn because one had hit a key other than :.
        !           814: There is an internal difference between "ex mode" (where it doesn't keep a
        !           815: screen image) and "vi mode" (where it does).  Any : command that outputs more
        !           816: than 1 line puts you into "ex mode", requiring "hit return to continue"
        !           817: before clearing the screen and redrawing it with known stuff.  There is no
        !           818: hope of this changing - the code is too spaghetti-ized already.  In the worst
        !           819: case, the ! command scribbles on the screen and there's nothing vi can do
        !           820: to know what the command did.
        !           821: 
        !           822: What you really want is for vi to check for typeahead and avert the refresh
        !           823: when it's going to have to redo it anyway.  My curses does this, but I simply
        !           824: don't have time to rewrite vi to use it.  This would also solve the other
        !           825: problem you mention where macros ought to redraw the screen only once.
        !           826: If you saw the insides of the code, you'd see it needs a rewrite to do this.
        !           827: Each command knows the screen things to do to fix the screen.
        !           828: 
        !           829: What most of us do is hit DEL when the screen is being drawn with something
        !           830: we don't want to see.  This aborts the update and leaves junk on the screen.
        !           831: Then you move the cursor where you want it, and if the screen is still
        !           832: garbaged, hit ^L.  Ugly but effective.
        !           833: 
        !           834:        "Using open mode"
        !           835:        Again, it took me a long time to learn that when I tried to enter
        !           836:        vi and got this diagnostic, it meant that the system had somehow
        !           837:        lost the termcap for the terminal I was on, and that I would have
        !           838:        to do something to get the correct termcap into the environment.
        !           839:        Till I realized this, I generally ended up either struggling along
        !           840:        frustrated in open mode, or logging out and logging back in.  I suggest
        !           841:        that when someone calls for vi and the termcap is not appropriate,
        !           842:        the editor should not be invoked in any form, but instead, a message
        !           843:        be given such as:
        !           844:             ``Your environment does not show a termcap entry permitting
        !           845:        the use of the visual editor.  If you are working on a terminal not
        !           846:        supporting vi (in particular, a device with no addressable cursor),
        !           847:        you may enter one of the other modes of the editor with the command
        !           848:        "open filename" or "ex filename".  If you are working on a terminal
        !           849:        that should support vi, your environment entries are incorrect and
        !           850:        should be corrected.  They presently show:
        !           851:             TERM=....
        !           852:             TERMCAP=....
        !           853:        If you know the correct name or abbreviation for your terminal-
        !           854:        type, type it at the end of the next line; if not hit return:
        !           855:             % setenv TERM ''
        !           856:             If the user typed an acceptable terminal-name, the message would
        !           857:        continue, telling how to get the appropriate termcap.  If the user
        !           858:        instead typed return, the message would ask him or her to type the
        !           859:        name of the manufacturer shown on the terminal, not
        !           860:        worrying about upper/lower-case distinctions, and a list of possible
        !           861:        terminal names and abbreviations would be given... .  This whole
        !           862:        program would not be part of the editor, so there would
        !           863:        be no problem of space within the existing crowded confines of
        !           864:        the editor code.
        !           865: This, of course, doesn't belong in vi, but in login or tset.  In fact,
        !           866: tset is much friendlier these days.  Vi will print a better diagnostic
        !           867: if it knows you're on a "generic" terminal type such as "dialup" - in
        !           868: terminfo there's a capability to indicate this, so it can print
        !           869:        I don't know what kind of terminal you have - all I have is "patchboard"
        !           870: 3.7 can't do this because it can't tell the difference between a generic
        !           871: terminal and a hardcopy terminal.
        !           872: 
        !           873:        "No such file or directory" -- I think there should be a distinction
        !           874:        between these two cases, because of the important distinction in the
        !           875:        consequences when the user tries to quit the editor:
        !           876: The kernel doesn't distinguish, so it's hard for vi to.  This is just a perror
        !           877: string.
        !           878:        If the directory exists, the file is created, but
        !           879:        if not, the results are more complicated -- I seem to recall on one
        !           880:        occasion simply losing what I had written on my second try
        !           881:        at quitting; though I just now did an experiment and this time
        !           882:        repeated ZZ's and :x's simply gave repeated error messages.
        !           883: Well, if it can't be reproduced, it doesn't stand much chance of getting fixed.
        !           884: (Not that it would if you could reproduce it, of course.)
        !           885: 
        !           886:        "File already exists..." -- The ``List of changes from 3.5 to 3.6'' says
        !           887:        ``If you get I/O errors, the file is considered "not edited"... .''
        !           888:        I presume that this correction is somehow the cause of the fact that
        !           889:        I frequently get the above message when trying to leave the editor
        !           890:        on a machine with version 3.7, and have to use
        !           891:              :w! %|q
        !           892: Ick!  Most of us just type
        !           893:        :wq!
        !           894: which is equivalent and much shorter.
        !           895:        to exit.  But I've never seen any evidence that there were I/O errors;
        !           896:        it mainly seems to happen when I've written some lines to another
        !           897:        file in the process of editing.  So the criteria the editor is using
        !           898:        to decide when there have been ``I/O errors'' should be rechecked.
        !           899: Actually, if you get ANY error (e.g. :foo<cr>) it resets the "buffer modified"
        !           900: condition.  I have finally been convinced this is not right.  For a while, I
        !           901: considered it a necessary evil in case your /tmp/Ex* file got an I/O error.
        !           902: 
        !           903:        "no such command from open/visual" -- This confused me in my first
        !           904:        few days of using the editor, when I didn't understand that one
        !           905:        couldn't use i and a (in either their vi or ex senses) from the bottom
        !           906:        line of vi.  A message "i -- no such command from open/visual"
        !           907:        was perplexing because I knew that "i" was indeed a vi command.
        !           908:        Perhaps it should say  "no such command from open/visual bottom line".
        !           909: OK.
        !           910: 
        !           911:        MISCELLANEOUS PROBLEMS
        !           912: 
        !           913:             In ex search and replacement patterns, \\ is supposed to represent
        !           914:        a real \-character, but something goes wrong when this occurs
        !           915:        at the end of a global command.  E.g., though
        !           916:             :s/^/\\
        !           917:        works OK (in vi or ex), the variant
        !           918:             :.g/^/s//\\
        !           919:        definitely does not.  In vi it turns everything off, in ex it seems to
        !           920:        behave as though there were just a single \, and in a scriptfile,
        !           921:        it -- does something still different, which you can discover if you
        !           922:        don't know!
        !           923: Backslash is special at the end of a line in global.  You need more \\'s.
        !           924: 
        !           925:        The Ex Reference Manual says, ``For sanity with use from within
        !           926:        visual mode, ex ignores a ":" preceding any command.''  But it
        !           927:        ignores it in the wrong place! -- not at the beginning of the
        !           928:        command line, but just before the command letter itself.  I.e.,
        !           929:        it accepts 1,3:s/^/     /, but not :1,3s/^/    /.
        !           930: Hmm.
        !           931: 
        !           932:        SUGGESTIONS FOR MINOR ADDED CAPABILITIES
        !           933: 
        !           934:           In a multiline substitute command with the "c" option, when
        !           935:        each line is displayed one has three choices: y, n or break.  There
        !           936:        are some further options that would be useful.  One would be "p" --
        !           937:        at present, "p" can only be included on the command line, which
        !           938:        means that one has a choice between seeing the result of every
        !           939:        substitution or none.  In practice, one would generally like to see
        !           940:        the results of the first few cases to make sure that the command one has
        !           941:        written does what one meant it to, and maybe a few tricky cases that
        !           942:        come up; but not every case!   Another might be "u" -- to undo the last
        !           943:        case for which one gave a "y".  Still another might be an option that
        !           944:        would mean ``undo the "c" option -- I see that the substitute command
        !           945:        is doing what I wanted, go ahead and finish it without me.''
        !           946: If I were going to do something this involved (I didn't know anybody used the
        !           947: c option anymore - most people use "n" and "." in vi) I would do query-replace
        !           948: ala EMACS right.
        !           949:            In a command  g/pattern/p,  the pattern in question is occasionally
        !           950:        such that it takes a while to figure out where on the line it occurs.
        !           951:        For this purpose, an option that ``pointed out'' the instance of the
        !           952:        pattern, in the same manner that the pattern to be replaced is pointed
        !           953:        out in substitute command with option c, would be desirable.
        !           954:            When  g/pattern/p  gives more than a screenful of lines, it would
        !           955:        be nice to have it piped through the equivalent of ``more''.
        !           956: Nice but unlikely.  Unless, of course, you have page mode in your tty driver,
        !           957: like we do, in which case you get it for free.
        !           958: 
        !           959:            ex has the command line option "-", which ``is useful in processing
        !           960:        editor scripts''.  But if one wants to use a script in the course of
        !           961:        an otherwise interactive editing session, it would be desirable to have
        !           962:        a corresponding resettable option ``:se -'' (or ``:se nofb'').
        !           963: Seems like a good idea.
        !           964: 
        !           965:             In strings in pattern-searches, it would be useful to have
        !           966:        ^ and $ retain their ``magic'', so that /x[a$]/ could
        !           967:        search for all occurrences of  x  before an  a  or a newline.
        !           968:        (Of course, one would then have to decide whether  /x[^y]/ should
        !           969:        include the case of  x  followed by a newline or not.)
        !           970: This sounds pretty hard to do.
        !           971: 
        !           972:            Just as ex allows the command :vi, so I think that vi should
        !           973:        have some bottom-line command equivalent to the regular-mode
        !           974:        command  Q.  When one has done some text-changing bottom-line
        !           975:        commands, and realizes one wants to go into ex, it can be time-
        !           976:        consuming to hit return and then Q, and wait for the screen to be
        !           977:        redrawn for vi before one gets the ex prompt.
        !           978: This would be ugly, since the ex command routine would have to return an
        !           979: indication to the vi routine to exit back to the top level ex command.
        !           980: But I suppose it could be done.
        !           981: 
        !           982:             The option of putting several commands on one line, separated
        !           983:        by, "|" is particularly useful in the vi bottom-line mode, because
        !           984:        it avoids having the screen redrawn several times.  It would be
        !           985:        useful to be able sometimes do the same thing with non-bottom-line
        !           986:        commands, e.g. in editing a troff file at a low baud rate on a dumb
        !           987:        terminal one might like to be able to do  i\fI^]3Ea\fR^]  without
        !           988:        watching the line get redrawn twice.  Perhaps some key that would
        !           989:        cause any sequence of commands to be ``held'' until some complementary
        !           990:        key was hit would be useful.
        !           991:             It would also be desirable to have a sequence of commands that had
        !           992:        been given in this way available as one unit to be repeated by ``.'',
        !           993:        if desired.
        !           994: See above.  And get yourself a terminal with insert/delete char!
        !           995: 
        !           996:             The parenthesis-matching facility with % might be extended
        !           997:        to match ` with ' and <  with  >.
        !           998: OK.
        !           999: 
        !          1000:             I will mention one facility that I discovered by surprize is
        !          1001:        possessed by  ed  but not  ex  --  sequences such as  \1  can be used
        !          1002:        within  ed  search-patterns.  E.g. (for the most trivial case)
        !          1003:             /\(.\)\1/
        !          1004:        will search for doubled letters.
        !          1005: This surprises me.
        !          1006: 
        !          1007: 
        !          1008:        DEBATABLE SUGGESTIONS
        !          1009:             I will mention here some possible changes which have the
        !          1010:        difficulty that they would change the meaning of existing commands,
        !          1011:        so that it could be argued that the disadvantage of users having
        !          1012:        to change their habits might outweigh the advantages.
        !          1013: 
        !          1014:             First, one might try to resolve, one way or another, the
        !          1015:        contradiction between the count arguments taken by the join commands
        !          1016:        in  vi and  ex:  In ex, jN joins N+1 lines; in vi, NJ joins N lines
        !          1017:        (except if N=1).
        !          1018: Yeah, ex should be N, not N+1.
        !          1019: 
        !          1020:             Second, the movement commands  tx  and  Tx  of vi (x any character)
        !          1021:        seem poorly defined.  Just as fx will ignore the character on which
        !          1022:        the cursor is presently sitting, even if it is an  x,  and move to the
        !          1023:        next occurrence, so I would think that  tx  should ignore the character
        !          1024:        immediately after the cursor, and  Tx  the character immediately before
        !          1025:        the cursor.  The point is that when one does  Nfx,  and finds that one
        !          1026:        had failed to count one occurrence of  x  and fallen short of where one
        !          1027:        wanted to go, one can hit  ;  and get there.  Likewise, on doing  Ntx
        !          1028:        and finding one has fallen short, one should be able to hit  ;  and get
        !          1029:        to the the next occurrence; but at present, hitting  ;  leaves
        !          1030:        the cursor in the same position; one must hit  ``2;''  to get any
        !          1031:        further.  In effect,  Ntx  is presently defined as  Nfxh;  I am
        !          1032:        suggesting that it be defined as  lNfxh.
        !          1033: Agreed.
        !          1034: 
        !          1035:             The sequences  cw, dw  and  yw  are presently violations of the
        !          1036:        principle that  c[movement],  d[movement]  and  y[movement]  change,
        !          1037:        delete, or yank everything from the current cursor position through
        !          1038:        the endpoint of the movement command.  cw does what one would expect of
        !          1039:        ce (in fact, they seem to be synonyms), while there is no way to get
        !          1040:        the effect which  cw  would have if it were treated ``consistently''.
        !          1041:        (E.g., if I have a line beginning  ``And if'', and I want to change it
        !          1042:        to ``If'', I cannot just put the cursor on the A and hit  cwI^].)  dw
        !          1043:        and  yw  delete up to the character immediately before the point to
        !          1044:        which ``w'' would take the cursor.  I would have to agree that this
        !          1045:        behavior of dw and  yw  is more useful than that which a literal
        !          1046:        interpretation of the movement rule would lead to; but perhaps it
        !          1047:        would become still more useful if when applied to the last word on
        !          1048:        a line, it deleted or yanked the space immediately before the word
        !          1049:        along with the word... .  On the other hand, one could argue for
        !          1050:        making a distinction between  cw  and  ce.
        !          1051: This is to make the user interface friendlier, and is a fact of life.
        !          1052: If I wanted to change "And if" to "If", I'd type "dw~".
        !          1053: 
        !          1054:             Though I see the motivation for the above definitions,
        !          1055:        I see no sensible reason why  Y  should be equivalent to  yy,  when
        !          1056:        C  and  D  are equivalent to  c$  and  d$.  I would vote for changing
        !          1057:        Y  to mean  y$.  
        !          1058: The users wouldn't stand for such a change.  Too many are used to it like it is.
        !          1059: But you could always map it.
        !          1060: 
        !          1061:        RADICAL SUGGESTIONS
        !          1062: 
        !          1063:             Is there any reason for maintaining the distinction between
        !          1064:        the ``:'' state of vi, and  ex  itself?  At present, there are
        !          1065:        relative advantages that lead one to choose to go into one or the
        !          1066:        other for a given operation:  From the vi-: state, it is easier
        !          1067:        to return to the regular vi state; from ex, one has a more powerful
        !          1068:        range of commands; and it is easier to give a series of commands
        !          1069:        because each carriage-return gives one a new prompt.  My suggestion
        !          1070:        is that from vi, ``:'' should carry you directly to ex, and when you
        !          1071:        are in ex, carriage-return (^M) after a command should give you a new
        !          1072:        prompt, while ^] should put you into vi.  Conceivably, things might be
        !          1073:        simplified even further, and carriage return rather than : could
        !          1074:        be the key that would carry one from the regular mode of vi into ex:
        !          1075: The basic problem here is that if : put you into ex mode, you'd have to redraw
        !          1076: the screen when you hit return.  The motivation for : commands is that you
        !          1077: don't have to go through a conceptually hard mode change and wait for a
        !          1078: screen redraw.
        !          1079: 
        !          1080:                                 .-------.      .-------.
        !          1081:                .-------. a,i... | basic |  ^M  |       |
        !          1082:                |  vi   |<------ |       |----->|  ex   |<---.
        !          1083:                | insert|        |   vi  |      |       |    |^M
        !          1084:                |  mode | ------>|       |<-----| mode  | ---'
        !          1085:                `-------'  ^]    |  mode |   ^] |       |
        !          1086:                                 `-------'      `-------'
        !          1087: 
        !          1088:        (Of course, ^M presently has a meaning in vi, but
        !          1089:        it has a synonym +.)  Clearly, there would also be no need for a
        !          1090:        special "Hit return to continue" state.
        !          1091:             I have not distinguished vi and open in the above diagram.
        !          1092:        My idea here is that ^] would actually return you to either vi
        !          1093:        or open, whichever you had last been in, and that to switch
        !          1094:        to the other, you could enter ex and type vi^] or o^] respectively.
        !          1095:        (Or you could type  vi^M, respectively o^M, and further ex commands,
        !          1096:        and the mode would be saved for the next time you hit a ^].)  Or
        !          1097:        alternatively, these could be made settable options: se visual
        !          1098:        respectively se novisual.
        !          1099:             Having gotten used to the editor as it now exists, I admit that
        !          1100:        I feel uneasy about the above idea -- the sense of knowing that
        !          1101:        I am ``still in vi'' when I hit :, and not that ``other land'' of ex, 
        !          1102:        represents a kind of of orientation that it is disconcerting
        !          1103:        to abandon.  But I can't see any logical disadvantage in making
        !          1104:        such a change.  Can you?  Certainly, there would be things that
        !          1105:        would have to be thought out, such as what happens to bottom-line
        !          1106:        vi pattern-searches.  My thought would be that ``/'' from vi should
        !          1107:        give :/ (i.e., put one in ex at the start of a pattern-search),
        !          1108:        and ^] after a pattern-search should put one into vi at the appropriate
        !          1109:        character on the line, in contrast to ^M after a pattern search,
        !          1110:        which would leave one in ex at the appropriate line.  In general,
        !          1111:        I think such changes would lead to greater simplicity and learnability
        !          1112:        of the editor.
        !          1113:             I would also hope that excursions between vi and ex and back
        !          1114:        could be allowed in scriptfiles.  It might also be desirable for
        !          1115:        ex to have, in addition to a concept of ``current line'', one of
        !          1116:        ``current cursor position''... .
        !          1117: 
        !          1118:             Well, on to another subject.  One of the inconveniences I
        !          1119:        found very vexing when first learning to use the editor was that
        !          1120:        when in either vi insert mode, or ex/vi-bottom-line, it was very hard
        !          1121:        to edit what I was doing.  Within insert mode the only ``editing''
        !          1122:        I could do, without escaping, was with the three operations ^H,
        !          1123:        ^W and the kill character.  And on a slow line with a dumb terminal,
        !          1124:        escaping to make changes could be very time-consuming because large
        !          1125:        parts of the screen would insist on being redrawn.  Perhaps some
        !          1126:        other control-character could serve as
        !          1127:        a modified escape, that allowed one to edit what one had entered
        !          1128:        in the current insertion without having everything below it redrawn,
        !          1129:        and then return to it.  Obviously, if carried to its logical
        !          1130:        limit this idea could lead to ridiculous nests of
        !          1131:        editing operations; but there would be no need to carry it to its
        !          1132:        logical limit.
        !          1133: Why not just get a terminal with insert char?  You're paying in performance
        !          1134: for having an obsolete terminal.
        !          1135:             Anyway, the problem of editing ex-style commands
        !          1136:        was even worse, because there was no way to ``escape and
        !          1137:        revise''.  I eventually learned enough to realize that the solution
        !          1138:        was to edit complicated commands in another file and source it.
        !          1139: This is a standard complaint about a moded editor.  It couldn't be fixed
        !          1140: without taking away the property of ESC ending command lines.  Besides,
        !          1141: allowing editing on the bottom line would really break a lot of code.
        !          1142:        But it is sometimes very useful to have the text on which the
        !          1143:        commands are to act in front of you when composing them (e.g., you can
        !          1144:        yank and modify various pieces), which led to the variant of writing
        !          1145:        command lines within the file I was editing, and then writing
        !          1146:        those lines into another file and sourcing that, without ever leaving
        !          1147:        the current file.  But this is distracting to deal with
        !          1148:        when concentrating on the editing task itself, which led me
        !          1149:        to divise a scriptfile which would handle the writing-to-another-file-
        !          1150:        and-sourcing for me.  Or actually, several such files:  One for
        !          1151:        single-line commands to be used essentially once; one for single-line
        !          1152:        commands that I would want to use on the same file during various
        !          1153:        editing sessions, and so would want to keep available in that
        !          1154:        file, and one for multi-line commands (to be used once).  When
        !          1155:        I first got the idea, I thought one scriptfile would be enough, and
        !          1156:        I would call it ``do'', so that the command to execute a script I
        !          1157:        had written in a file I was editing would be ``:so do''.  The
        !          1158:        file it would write to and source would be ``do.again'', so that
        !          1159:        if I wanted to reuse it, I could ``:so do.again''.  When I realized
        !          1160:        the need for several versions, ``do'' became a directory.  Here,
        !          1161:        for your amusement, are the three files.  (Re the lines ``se prompt'',
        !          1162:        cf. my comment on that under PROBLEMS WITH SOURCE etc.):
        !          1163: 
        !          1164:          do/1  (for 1-time use of 1-line commands)
        !          1165:                .w! ~/do/again
        !          1166:                d
        !          1167:                so #
        !          1168:                se prompt
        !          1169: 
        !          1170:          do/1+  (like above, without deleting the command)
        !          1171:                .w! ~/do/again
        !          1172:                so #
        !          1173:                se prompt
        !          1174: 
        !          1175:          do/:  (to use this, write a multi-line command script, put : at
        !          1176:          the beginning of the first line, put the cursor on the last
        !          1177:          line of the script, and then source the following:)
        !          1178:                ?^:?s/:/
        !          1179:                ,''w! ~/do/again
        !          1180:                ,''d
        !          1181:                so #
        !          1182:                se prompt
        !          1183: 
        !          1184:        (I also created another version to use in case the script had
        !          1185:        to have an internal line beginning with ``:'', so that this couldn't
        !          1186:        unambiguously mark the beginning of the script.  This used
        !          1187:        a line which explicitly specified the address-range of the script.
        !          1188:        But I have never had a need for it, so I will not bother you with it.)
        !          1189:            Finally, having gotten an account on a machine with a version 3
        !          1190:        editor recently, I have divised still another way of doing this.  I
        !          1191:        have put in my EXINIT the command
        !          1192: 
        !          1193:                'map ^A "ayy:@a^M'
        !          1194: 
        !          1195:        and now, gratifyingly, the single stroke ^A has essentially the effect
        !          1196:        of ``:so do/1+''  -- except for the restrictions to which vi ``map''
        !          1197:        commands are subject.  But I've only been using this for a
        !          1198:        couple of weeks; so I have yet to learn how chafing those restrictions
        !          1199:        will or won't be.
        !          1200:             Anyway, it might be worth thinking about whether some of these
        !          1201:        things that I've done with macros should be incorporated in some form
        !          1202:        into the editor itself; or else whether these macros might be written
        !          1203:        up in the documentation (or some tutorials) on the editor.
        !          1204: 
        !          1205:             Next subject: Complicated pattern-searches in long files
        !          1206:        can be time-consuming.  I have seen the point mentioned
        !          1207:        that if a pattern-description can be begun with "^",
        !          1208:        this can speed up the search -- since the pattern-comparisons need
        !          1209:        only be begun at beginnings of lines.  In some cases, this might
        !          1210:        not be possible, but the user might be aware of some other
        !          1211:        character or character-sequence in the search-pattern
        !          1212:        that will occur relatively rarely in the file.  In such cases it would
        !          1213:        be desirable if the user could specify one spot from which the pattern
        !          1214:        search should start, working forward and backward from there, to
        !          1215:        minimize false starts.  E.g., if for some reason one wants to
        !          1216:        delete every word containing the letter m, the script
        !          1217:                %s/[^ ]*m[^ ]*//
        !          1218:        would become much less time-consuming if one could mark the point
        !          1219:        at which to begin, say writing
        !          1220:                %s/[^ ]*\!m[^ ]*//
        !          1221:        so as to instruct the editor to search for m's, and each time
        !          1222:        one was found, to find the longest possible strings of non-space
        !          1223:        characters before and after it, and delete these.   (This is a silly
        !          1224:        example, but I think the idea is clear.)
        !          1225: Isn't worth doing - this is fast enough for most people in most cases.
        !          1226: 
        !          1227:             Something that I've seriously felt the need for is the
        !          1228:        capability of searching for lines that satisfy more than one
        !          1229:        condition.  If one just wants to locate such lines, one can
        !          1230:        of course leave the editor and do a pipeline of two or
        !          1231:        more greps; but it would be nice to be able to perform global
        !          1232:        commands on such lines.
        !          1233: You want the PWB "or" operator.  This is hard to put in - their code
        !          1234: is really convoluted.
        !          1235: 
        !          1236:            Finally, any possibility of introducing the capability of searching
        !          1237:        for patterns including embedded newlines, a la sed?
        !          1238: Newlines aren't stored - the data structure is an array of lines.
        !          1239: So this is nearly impossible.
        !          1240:        Multiple windows, a la emacs?
        !          1241: Would be easy after a rewrite, but impossible with current code.
        !          1242: What you really want is a window manager, anyway, most of the time.
        !          1243: 
        !          1244:        ADDENDA
        !          1245:             I logged in this morning on an adm3a at 300 baud to go over this
        !          1246:        letter once more before sending it, and ran into another bug!  I had
        !          1247:        done 15^D to get a large scroll despite the low speed, and at one point
        !          1248:        I saw a line with a typo scrolling up.  So I noted its line-number, 402
        !          1249:        and without waiting for the screen to stop moving typed something like
        !          1250:        402Gfsrd.  What happened was that the change was made on line 407 rather
        !          1251:        than 402 -- presumably the cursor was sent to where 402 had been when
        !          1252:        the command was received... .
        !          1253: Knowing the internals of vi, I'd say this is impossible.  It probably just
        !          1254: screwed up your screen from line noise (or your terminal isn't truly full
        !          1255: duplex), or you got the wrong line number.
        !          1256:             Editing this letter this morning reminded me of another feature I
        !          1257:        have thought would be desirable for editing on dumb terminals at low
        !          1258:        speeds:  An option that would cause lines read from a file or typed
        !          1259:        in at the bottom of the screen to appear double spaced, with @ signs
        !          1260:        @
        !          1261:        between them, such as one gets when one deletes a line on such a
        !          1262:        @
        !          1263:        terminal.  (I have faked this effect here, though the fake will not be
        !          1264:        @
        !          1265:        very successful if you have  se nu  or  se list  on.)  The point is that
        !          1266:        @
        !          1267:        editing operations that presently cause painfully slow screen-redrawings
        !          1268:        would simply put material in in place of these fillers -- as happens
        !          1269:        now when one is lucky enough to be adding material just above a place
        !          1270:        where material was previously deleted.
        !          1271: Again, it would cost less to buy a real terminal.  You can get one for $500
        !          1272: or so now from Falco or Liberty or Zenith.
        !          1273: 
        !          1274: Thanks again for the input.
        !          1275: 
        !          1276:        Mark
        !          1277: 
        !          1278: 
        !          1279: From gbergman@UCBCARTAN Fri Jul 29 16:07:10 1983
        !          1280: Date: 29 Jul 83 16:02:06 PDT (Fri)
        !          1281: From: gbergman@UCBCARTAN (George Mark Bergman)
        !          1282: Subject: editor
        !          1283: Message-Id: <[email protected]>
        !          1284: Received: by UCBCARTAN.ARPA (3.342/3.7)
        !          1285:        id AA09635; 29 Jul 83 16:02:06 PDT (Fri)
        !          1286: Received: from UCBCARTAN.ARPA by UCBERNIE.ARPA (3.336/3.7)
        !          1287:        id AA06658; 29 Jul 83 16:07:04 PDT (Fri)
        !          1288: To: cc-03@ucbcory, danh@kim, lindahl@topaz, mckusick@ernie, ralph@ucbarpa
        !          1289: Status: RO
        !          1290: 
        !          1291: 29/7/83
        !          1292:     I got a reply from Horton: a copy of my (first) letter,
        !          1293: annotated with comments that this should indeed be fixed, that
        !          1294: would be impossible, etc..  I'll send a copy to anyone who'd
        !          1295: like (or a copy of his comment on some specific bug they're
        !          1296: interested in).  Meanwhile, I'll send you my reply to him, since
        !          1297: it discusses still more bugs and possible improvements.
        !          1298: 
        !          1299: Dear Mark,
        !          1300:      Got your comments on my first letter!  Did you get the second,
        !          1301: shorter one?  Glad to see that some things, at least, can be fixed.
        !          1302:      Robert has put version 3.9 on this machine and I'm using it.
        !          1303: Using movement arrows within insert mode is amusing; though when there
        !          1304: is documentation, there should be a warning to the user that these
        !          1305: prevent ``u'' from undoing anything before those commands.  But
        !          1306: the first thing there needs to be documentation for is vedit!  Is
        !          1307: any being written?
        !          1308:      In your comment on ``Can't yank inside global/macro'' you said
        !          1309: that one can, of course, always yank to a named buffer.  I checked,
        !          1310: in the case of @a scripts, and the answer is yes and no:  The yank
        !          1311: works, but one still gets that diagnostic, and anything else in the
        !          1312: sequence of commands is aborted.
        !          1313:      And concerning the diagnostic ``Can't undo in global commands'' --
        !          1314: I understand what you say about why one can't, but it still seems an
        !          1315: unenlightening and perhaps inappropriate diagnostic to get when one has
        !          1316: done  @a  and buffer  a  contains say
        !          1317:        x:g/foo/s//bar
        !          1318: Here the initial ``x'', deleting the character the cursor was on when
        !          1319: the command was given, creates the text-modified condition which,
        !          1320: as I mention, seems to cause globals in @-scripts to give this
        !          1321: diagnostic.  I've just tested the above script -- several times,
        !          1322: because I found it hard to believe what was happening -- and it did
        !          1323: indeed give the diagnostic in question, but instead of replacing foo's
        !          1324: with bar's, it replaced the first line containing a foo with a copy of
        !          1325: the last line of the file! I leave it to you to figure that one out!
        !          1326: (This is on version 3.9.  Incidentally, I've used a true ^M in that
        !          1327: script, so it is ready for you to try.)
        !          1328: 
        !          1329:      Further observations on some of the bugs I mentioned in my
        !          1330: second letter:  The business with  yb  is both more general and more
        !          1331: complicated than I realized.  The general fact seems to be that when
        !          1332: one does a yank to a position earlier on the same line, the cursor does
        !          1333: not move, but the editor thinks it has, so that any subsequent command,
        !          1334: e.g. a movement, a delete, etc., has the effect that it would if it had
        !          1335: been done with the cursor starting from the new position.  The
        !          1336: complication is that yanks to named buffers don't behave the same as
        !          1337: simple yanks: They also leave the cursor unmoved, but what they actually
        !          1338: yank into the buffer is the text from the cursor location to the end of
        !          1339: the line; and whether they cause the editor to consider the cursor to
        !          1340: be in a different location from where it really is seems to depend on
        !          1341: the movement in question:  with "ayNb, no, with "ayN|, yes (where N
        !          1342: again stands for a positive integer).  So what I called a snake in the
        !          1343: grass seems to be a can of worms!
        !          1344:      In experimenting with this, incidentally, I've found that, while a
        !          1345: put from a named buffer can be undone with u, if one attempts the
        !          1346: command U, ``undo all changes made since coming onto this line'', only
        !          1347: changes made since the last named-buffer-put are undone.
        !          1348:  
        !          1349:      I mentioned various abbreviations that were hard to unabbreviate,
        !          1350: but could be done with the help of ^V -- but that I had found no way
        !          1351: to undo
        !          1352:        :ab if if\pq
        !          1353: To be precise, I had found that  :una ^Vif,  :una ^V^Vif,  and
        !          1354: :una    ^Vif  where each ^V represents two ^V's typed in, didn't work.
        !          1355: I've finally found something that does:  :una i^Vf.
        !          1356: 
        !          1357:      I find the diagnostic ``No tail recursion'' strange,
        !          1358: since the occurrence of an abbreviation at the end of the item
        !          1359: abbreviated shouldn't cause a recursive loop; while circumstances that
        !          1360: do cause such a loop, namely the occurrence of the abbreviation within
        !          1361: the item abbreviated, preceded by a space and followed by punctuation,
        !          1362: are not censored, e.g. :ab x ( x ), or with more subtle effect,
        !          1363: :ab x x sup 2.
        !          1364:      It seems that if one has :ab x word,  then the abbreviation works
        !          1365: when x is preceded by a beginning-of-insert, a space, a tab, or a
        !          1366: newline, and followed by most any nonalphabetic character.  For
        !          1367: word-processing use, it would be natural to allow it to also be
        !          1368: preceeded by (, ", `, [, perhaps even a user-specified set of
        !          1369: characters.
        !          1370: 
        !          1371:      To my list of vi commands which I think should be able to take
        !          1372: counts, add p and P.  I often want to put in a large number of copies of
        !          1373: one or more lines, as ``forms'' in which I will enter various kinds of
        !          1374: additional data, and it would be convenient to be able to do compose
        !          1375: such a line and then duplicate it the desired number of times all at
        !          1376: once.  What I currently do is produce a copy and then go
        !          1377: yypk2yypk4yyp... till I have enough.
        !          1378: 
        !          1379:      Two more commands I think would be useful:  (1) One which "puts" to
        !          1380: the screen (in the sense of g/pattern/p, i.e. without affecting the
        !          1381: buffer) the contents, or the first lines in cases that are longer than
        !          1382: one line, of all nonempty buffers, named or numbered, with an
        !          1383: indication, of course, of which each was.  (Ideally one would like to
        !          1384: be able to specify some subset of the buffers, whether one wants the
        !          1385: first line, or everything, or some specified number of lines, etc..) 
        !          1386: (2) One which would show the script of the command stored to be used as
        !          1387: ``.''.  (And perhaps ditto with the last search pattern.)
        !          1388:      Oh, yes: it would also be nice to have a way to give commands
        !          1389: without having them displace the one specified to be repeated by ``.'',
        !          1390: e.g. if one wants to do a certain change time after time at various
        !          1391: points in the file (using ``n'' and ``.'') but occasionally sees other
        !          1392: changes to be made along the way.  An alternative to the above would be
        !          1393: a way to read the command stored to be used as ``.'' into a named
        !          1394: buffer, so that one can give other commands and then return to
        !          1395: that one.  This would also allow one to reread the text of the command:
        !          1396: useful if it isn't behaving as one meant it to.
        !          1397:      
        !          1398:      You might as well send any future mail to me here as
        !          1399: gbergman@cartan -- I was using brahms while cartan's terminals were
        !          1400: being moved but I'll probably be using cartan more from now on.  But
        !          1401: I'll check mail on both.  (However, I'll be on vacation in New York
        !          1402: State from the 3d to the 16th of August.)
        !          1403:                                                Best regards,
        !          1404:                                                George
        !          1405: 
        !          1406: From gbergman@ucbcartan Fri Sep 23 13:57:06 1983
        !          1407: Date: Fri, 23 Sep 83 13:53:36 PDT
        !          1408: From: gbergman@ucbcartan (George Mark Bergman)
        !          1409: Message-Id: <[email protected]>
        !          1410: Received: by ucbcartan.ARPA (4.6/3.7)
        !          1411:        id AA02960; Fri, 23 Sep 83 13:53:36 PDT
        !          1412: Received: from ucbcartan.ARPA by UCBERNIE.ARPA (3.336/3.7)
        !          1413:        id AA20684; 23 Sep 83 13:57:01 PDT (Fri)
        !          1414: To: cc-03@ucbcory, danh@kim, lindahl@topaz, mckusick@ucbernie, ralph@ucbarpa
        !          1415: Status: RO
        !          1416: 
        !          1417: Latest letter on ex~vi to Horton:
        !          1418: 
        !          1419: Dear Mark,
        !          1420: 
        !          1421:      I hope I can assume that after my long letter to which you
        !          1422: replied, you did get my two shorter notes (one sent the same day,
        !          1423: the other about a week later); and that you've simply been to busy
        !          1424: to think about them or reply.
        !          1425:      However, since I have had bad experiences with Mail, I am worried
        !          1426: that either you may never have gotten them or that you may have replied
        !          1427: and your replies not reached me.  I hope you can send me a one-liner to
        !          1428: relieve my doubts.
        !          1429: 
        !          1430:      Not many bugs to report this time, but I will modify or discuss
        !          1431: a few of the suggestions I've made before.
        !          1432: 
        !          1433:      One that I want to modify is my suggestion that % should also
        !          1434: match < with > and ` with '.  All right in itself, but terrible if it
        !          1435: would also mean that with  :set match,  every time one typed a > or a '
        !          1436: the cursor would look for the last occurrence of < or `, since <, >, and
        !          1437: ' can occur in ways that have nothing to do with matching.  So I think
        !          1438: that making matchable pairs user-specifiable would be much more useful.
        !          1439: Faith Fich (who send her regards -- she and Mike were our neighbors till
        !          1440: a month ago, but have left for their new jobs at U. Seattle) suggested
        !          1441: that user-settable matches would be particularly useful for those
        !          1442: like herself who use distinct opening and closing delimiters with eqn.
        !          1443: Actually, on further thought this isn't quite right, since eqn
        !          1444: delimiters behave differently from parentheses -- if I want to use =
        !          1445: as my delimiter to enter equation mode, and & as my delimiter to leave
        !          1446: it, then eqn will not give any special treatment to &'s in text mode or
        !          1447: ='s in equation mode; so perhaps a different kind of matching for
        !          1448: that kind of use might be desirable; one would set  :set dmatch =&
        !          1449: for the delimiters suggested above; or :set dmatch $$  if one uses  $
        !          1450: for both delimiters as in the eqn tutorials.  I know checkeq is
        !          1451: supposed to serve this function; but it would certainly be convenient
        !          1452: to have it in the editor; and anyway, my experience was that checkeq
        !          1453: didn't understand that one could have distinct opening and closing
        !          1454: delimiters.  (But this is a disinterested suggestion; I haven't used
        !          1455: eqn for a long time; I put in my equations in raw troff.)
        !          1456: 
        !          1457:      The suggestion in my long original letter about an alternative to
        !          1458: the diagnostic "using open mode" was based on a misunderstanding -- but
        !          1459: one that might be worth making a reality.  I had been assuming,
        !          1460: since tutorials referred to the "three states" ex, vi, and open, and
        !          1461: since I knew one could enter the editor by typing  % ex filename or
        !          1462: % vi filename, that a third way to enter the editor was by typing
        !          1463: % open filename, and that this is what one should do when editing
        !          1464: with a device not having an addressable cursor (which I had never done).
        !          1465: So I supposed that the diagnostic "using open mode" would only be
        !          1466: received if one were trying to use the wrong mode of the editor for the
        !          1467: tty type shown in  one's environment.  Perhaps one should indeed have
        !          1468: special way to enter the editor when one intended to edit in "open
        !          1469: mode".  (If "open" has other uses as a command, the command might be
        !          1470: "vo" or "op".)  Then if a user gave the command vi and his
        !          1471: environment did not indicate a device with an addressable cursor, it
        !          1472: would indeed be appropriate to give a diagnostic informing him that his
        !          1473: environment was not compatible with this command.  I suggest this
        !          1474: because of the frustrating experiences I had as a beginner, of
        !          1475: being put into open mode (because my tty type had somehow been lost)
        !          1476: and not knowing what I could do about it.
        !          1477: 
        !          1478:      I am somewhat confused by your explanation that editor scripts
        !          1479: that would go back and forth between ex and vi modes (using the :vi
        !          1480: and Q commands) are impossible because "The internals of getting a
        !          1481: character from the tty are completely different in ex and vi.  Pushing
        !          1482: input for one doesn't affect the other."  A vi "script" (i.e. a mapping
        !          1483: or a macro called by @x) can presently include bottom-line commands
        !          1484: called with ":".  I would suppose that the way such commands get
        !          1485: characters from the terminal is about the same as the way ex does.
        !          1486: You also write that "Any : command that outputs more than 1 line puts
        !          1487: you into "ex mode"," -- is this a different sense of "ex mode"?  If
        !          1488: not, what happens when a vi script does this?
        !          1489:      I mentioned that the :so command from vi ignored anything after
        !          1490: any global command in the sourced file.  I also find that it will not
        !          1491: accept the ex commands i and a; I realize that a prohibition against
        !          1492: these is part of the way vi's bottom line differs from genuine ex.
        !          1493: I've just done some experimenting, and I find that a script sourced
        !          1494: from the bottom line of vi also interprets the command vi as a command
        !          1495: to edit another file.  Do we really want script files to be interpreted
        !          1496: so differently when sourced from ex mode and from the bottom line of vi?
        !          1497: Or if these differences are inevitable, can't the vi version at least
        !          1498: have the positive difference of being able to go to visual mode with
        !          1499: ^M^M or something, and continue following the script, interpreting
        !          1500: characters as screen mode commands, just as a mapping or @x macro will
        !          1501: if it has gone down to the bottom line with ":" and come back again?
        !          1502:      I am also still reluctant to give up the idea of a version of the
        !          1503: editor in which there is no difference between the line-oriented mode
        !          1504: and the bottom line of the visual mode.  Suppose you took the editor as
        !          1505: it exists now, and modified it so that in visual mode, ":" was
        !          1506: interpreted as "Q", and in ex mode, ^[ was interpreted as ^Mvi.  The one
        !          1507: obvious disadvantage would be that it would insist on redrawing the
        !          1508: screen after minor editing operations in ex mode.  So suppose you made
        !          1509: it remember the previous state of the screen every time it entered ex
        !          1510: mode, and make the necessary adjustments on return to visual mode if the
        !          1511: editing done was fairly trivial -- using the same criteria it now uses
        !          1512: after bottom-line commands.  What would be the problem?
        !          1513:      Of course, I know I am quite ignorant of what is involved, and what
        !          1514: I am suggesting as possible may be quite impossible, or may have to wait
        !          1515: for that far-off day when you rewrite the editor.
        !          1516: 
        !          1517:      You write that some of the restrictions on global commands are due
        !          1518: to the fact that the state of the buffer before the command is stored in
        !          1519: the "last deleted" buffer.  But couldn't this situation be modified?
        !          1520: Let's call the "last deleted" buffer buffer 0, since material from it
        !          1521: seems to progress up to 1, 2, etc. with successive changes made.
        !          1522: Suppose things were set up so that during the operation of a global or
        !          1523: macro, deleted material, yanked material, etc. went by default into
        !          1524: buffer 1 instead of 0...?  Or alternatively, that the state before the
        !          1525: global were saved in buffer 9, and this was then set outside of the
        !          1526: chain of buffers into which material got pushed with successive
        !          1527: deletions, during the operation of the global?  Would this eliminate
        !          1528: the objection to nested globals as well?  Presumably, in a global within
        !          1529: a global, the previous state would be stored in buffer 1, and new yanks
        !          1530: put by default in buffer 2 (if the first of the above suggestions were
        !          1531: followed).
        !          1532:      You mention in your comments to my letter that the difficulty of
        !          1533: editing command lines "is a standard complaint about a moded editor"
        !          1534: that would be hard to fix.  But I point out in that same letter how
        !          1535: appropriate macros or script-files can overcome that difficulty.  (My
        !          1536: files "do/1", "do/:" and the "map ^A ..." in my EXINIT.)  It should be
        !          1537: possible to introduce commands that would have the
        !          1538: same effects as those macros.  (Or at least, to describe such macros
        !          1539: in the documentation.  I have realized, by the way, that ^A was a poor
        !          1540: choice of character for me to map, because it occurs in the output of
        !          1541: function keys on a lot of terminals.)
        !          1542: 
        !          1543:      It would be nice to extend the kinds of "regular expressions"
        !          1544: allowed in searches, e.g. a la egrep.  Sometimes I also want to indicate
        !          1545: something like "a substring of precisely 40 characters".  This can be
        !          1546: rendered as "........................................" at present,
        !          1547: but things like that can easily lead to commands that
        !          1548: exceed length limits.  (Suppose one wants to look for a string of
        !          1549: 40 successive characters other than whitespace.  [^ ][^ ][^ ] ... is
        !          1550: too long.)  Have you checked out what I mentioned in my first long
        !          1551: letter, that ed allows you to search for (e.g.) successive
        !          1552: identical characters as \(.\)\1?
        !          1553: 
        !          1554:      Let me pass on a suggestion made recently in a system message by
        !          1555: someone named nye.  He was worried about what would happen
        !          1556: if while one person was editing a file, someone else with write
        !          1557: permission for that file also began editing it.  Presumably, whoever
        !          1558: did a "write" last would overwrite the other person's work.  He
        !          1559: suggested that there be a diagnostic "file has been changed since last
        !          1560: write" for such a situation.  (In particular, he wondered what would
        !          1561: happen if he got his mail by editing /usr/spool/mail/name, rather than
        !          1562: by using Mail -- which is certainly tempting if one is more comfortable
        !          1563: with the editor than with Mail -- and if unbeknownst to him new mail
        !          1564: arrived while he was editing.)
        !          1565: 
        !          1566:      I have discovered the hard way that when one has done a
        !          1567: vi -r filename  and decided one was satisfied with the version that
        !          1568: was saved, ZZ or :x are  n o t  the same as  :wq  -- the first two
        !          1569: discard the saved file, and only the last one writes it over the
        !          1570: previous version.  (I actually haven't checked this out on version 3.9.
        !          1571: I tried to, and found that robert hadn't brought
        !          1572: /usr/lib/ex3.9{preserve,recover}, if that's what they're still
        !          1573: called, from arpa along with the rest of 3.9.  But he's getting them for
        !          1574: me.)  If you don't want to make  ZZ  and  :x  actually equivalent to
        !          1575: :wq, you might at least make them give error messages forcing the
        !          1576: user to make the explicit choice of :wq to keep the saved version, or :q
        !          1577: to discard it.
        !          1578: 
        !          1579:      I've been having fun using recursive "map" commands from time to
        !          1580: time.  For example, a file of mailing addresses of Math Departments is
        !          1581: being prepared, for use with a new Computer Services command "label".
        !          1582: This requires that each address constitute one line of the file, with
        !          1583: the intended lines of each label separated by
        !          1584: semicolons rather than newlines, each being no longer than 34
        !          1585: characters.  At present, the lines in the file are of the form
        !          1586: [university-name];[city-state-zip]
        !          1587: and I wanted to find cases where the university name the secretaries
        !          1588: had typed in was over 34 characters long.  So I did
        !          1589: :map ^A +36^V|F;^A0
        !          1590: Then, when I hit ^A, the cursor went bopping down the file, passing
        !          1591: through each line at which it could find a ";" before the 36th position,
        !          1592: but stopping when it hit a line where it could not.  When I had
        !          1593: corrected such a line, by abbreviating a long word or whatever, I could
        !          1594: hit ^A again and find the next case.  The "0" at the end of the map
        !          1595: command is to prevent the "No tail recursion" rule from aborting my
        !          1596: mapping.  It has no other effect, because it is never reached.
        !          1597:      Of course, the above example of a recursive mapping is guaranteed
        !          1598: to stop eventually, if only by reaching the end of the file.  But I find
        !          1599: that mappings that can go on indefinitely are very hard to stop.  E.g.
        !          1600: :map q ax^[q0
        !          1601: I've tried some like that, and sometimes hitting <break> or whatever
        !          1602: enough times successfully stops them (often leaving a bit of a mess --
        !          1603: characters that ought to have come after the string of x's embedded
        !          1604: among them), while other times the only thing I can do is to go to
        !          1605: another terminal and kill the editing process.  Maybe it is to prevent
        !          1606: things like that that you put in the "No tail recursion" rule --
        !          1607: though clearly it can be gotten around.  Might it not be better to
        !          1608: somehow make the editor not quite so deaf to <break>s during such a
        !          1609: process?
        !          1610: 
        !          1611:      I will mention one curious experience which I have not been able to
        !          1612: reproduce.  I use :set nu.  After a delete near the beginning of a file,
        !          1613: I found myself looking at a screen with line-numbers beginning around
        !          1614: -2!  The lines with nonpositive numbers were blank, if I recall; lines
        !          1615: 1, 2, etc. were as they should be.  I mentioned this to someone
        !          1616: who said he'd had the same thing had happened at times, but had
        !          1617: never been able to figure out what conditions caused it.
        !          1618: 
        !          1619:                                        Best regards,
        !          1620:                                        George
        !          1621: 
        !          1622: From gbergman@ucbcartan Thu Nov  3 22:32:01 1983
        !          1623: Received: from ucbcartan.ARPA by ucbernie.ARPA (4.17/4.13)
        !          1624:        id AA25163; Thu, 3 Nov 83 22:31:44 pst
        !          1625: Date: Thu, 3 Nov 83 22:28:11 PST
        !          1626: From: gbergman@ucbcartan (George Mark Bergman)
        !          1627: Message-Id: <[email protected]>
        !          1628: Received: by ucbcartan.ARPA (4.6/3.7)
        !          1629:        id AA06097; Thu, 3 Nov 83 22:28:11 PST
        !          1630: To: cc-03@BERKELEY, danh@kim, lindahl@topaz, mckusick@ucbernie, ralph@ucbarpa
        !          1631: Status: R
        !          1632: 
        !          1633: Latest letter to Mark Horton re editor bugs etc.:
        !          1634: 
        !          1635: copies sent to
        !          1636: cc-03@ucbcory
        !          1637: ralph@ucbarpa, lindahl@topaz, mckusick@ucbernie 25/7/83
        !          1638: danh@kim  26/7
        !          1639: Mark Horton's reply: anderson@kim 30/7/83
        !          1640: 
        !          1641: Dear Mark,
        !          1642:      I got your reply to my last letter, but you don't say
        !          1643: whether you got the two preceding ones -- in particular, I'm
        !          1644: curious as to what you'd say about the peculiar behavior of
        !          1645: abbreviations terminated by \[character].  (E.g., suppose
        !          1646: someone did :ab ac artistic, and then, supposing the file was for
        !          1647: troffing, typed ac\fP. -- Try it!)  And likewise, about what
        !          1648: happens if you hit  @x,  when register  "x  contains
        !          1649:        x:g/foo/s//bar
        !          1650: (To see this wierd effect, you have to have a file with
        !          1651: an occurrence of ``foo'', and a distinctive  l a s t  line.)
        !          1652: 
        !          1653:      In an earlier letter I commented that the mapping that
        !          1654: the editor sets up to enable the tvi's right-arrow key makes
        !          1655: ^L unavailable for refreshing the screen.  You replied that,
        !          1656: of course, the editor could not distinguish a ^L generated by
        !          1657: the arrow key from one typed as <ctrl>-L by the user.  True,
        !          1658: but some users, such as myself, are quite happy using hjkl
        !          1659: to move around the screen (I use them completely by reflex)
        !          1660: and so have no wish to enable special arrow keys, but do
        !          1661: want to have ^L available to redraw the screen when
        !          1662: a message or something messes it up.
        !          1663:      The problem with ^L occurred in using a tvi; now, using
        !          1664: a Z29 (in h19 mode), another version of the problem arises.
        !          1665: It has arrow keys that transmit things like ^]A, ^]B, etc.,
        !          1666: and version 3.9 not only maps these sequences, but also
        !          1667: map!s them.  What I found happening is that if in typing
        !          1668: I made a change somewhere in the body of a line and then
        !          1669: wanted to add something at the end of the line, I would often
        !          1670: type a  ^]  to end the first change and then an  A  to
        !          1671: begin the second, with less than a second between them, and
        !          1672: this sequence would then be map!ed into  ^]ka  or
        !          1673: something, landing me in a different place from the one
        !          1674: I wanted.  Aside from this major problem, there is the minor
        !          1675: inconvenience that the  map!  mechanism apparently waits
        !          1676: a second every time I type an  ^]  from insert mode to see
        !          1677: whether this is going to be one of the map!ed sequences, and
        !          1678: this makes exiting from insert mode sluggish.  My temporary
        !          1679: solution has been to write a file of the form
        !          1680:        unmap ^]A| unmap ^]B| ...|unmap! ^]A| unmap! ^]B| 
        !          1681: which I source every time I go into vi on the Z29.  I
        !          1682: guess what I should do is create simplified termcaps that
        !          1683: leave out the arrow keys for my own use when in version 3.7.
        !          1684: Kevin Layer tells me that when he puts 3.9 on all systems here,
        !          1685: there will be documentation on how to create terminfo files;
        !          1686: so I will be able to avoid these inconveniences in 3.9 as well.
        !          1687:      What would be better, for these two-or-more character sequences,
        !          1688: though, would be if the "timeout" feature on mappings
        !          1689: could involve a variable interval, which could be set in the
        !          1690: millisecond range for terminal-generated sequences (I suppose
        !          1691: it would have to depend on the baud rate), and longer
        !          1692: for user-mapped sequences.  The likelihood of the user
        !          1693: accidentally typing in one of the special sequences so fast
        !          1694: is negligible.
        !          1695:      Incidentally, I notice that when I type :map  to look
        !          1696: at the automatic mappings, these are labeled "up", "down" etc.,
        !          1697: though for mappings that I create the corresponding position
        !          1698: just shows a repeat of the mapped sequence.  Is there
        !          1699: any way the user can put mnemonics in with his own mappings?
        !          1700: 
        !          1701:      Two other minor points:
        !          1702: 
        !          1703:      In your reply to my first letter, where I suggested that
        !          1704: N/pattern should take one to the Nth occurrence of /pattern,
        !          1705: you said that N/pattern actually resets the window size to N
        !          1706: while carrying one to /pattern.  The tutorial says the same,
        !          1707: I believe, but nonetheless, it doesn't work!
        !          1708:      When one has pulled a command into a buffer,
        !          1709: say "x, and invoked it with @x, if one then tries to get
        !          1710: a copy of this command by doing "xp, it doesn't seem to work.
        !          1711: The way I've found to make it work is to do any other
        !          1712: yank-and-put (using, say, the last-deleted
        !          1713: buffer).  This somehow unfreezes the mechanism, and (after undoing
        !          1714: this last put, unless one wanted it), one can then successfully
        !          1715: do "xp.
        !          1716:                                Yours,
        !          1717:                                        George
        !          1718: 
        !          1719: (Message inbox:32)
        !          1720: Date: Sun, 10 Jun 84 16:29:50 pdt
        !          1721: From: gbergman@ucbcartan (George Mark Bergman)
        !          1722: To: cc-03@ucbcory, danh@kim, decvax!tarsa, gbergman@ucbcartan,
        !          1723:         hplabs!intelca!omsvax!isosvax!root, ihnp4!burl!we13!ltuxa!jab,
        !          1724:         leblanc@ucbdali, lindahl@topaz, mckusick@ucbernie, [email protected],
        !          1725:         ralph@ucbarpa, reiser@ruby, [email protected], unisoft!eryk,
        !          1726:         uw-beaver!ubc-vision!mprvaxa!sonnens
        !          1727: Subject: more editor bugs & ideas
        !          1728: 
        !          1729:      Here's another letter of comments on the editor that I'm
        !          1730: sending to Mark Horton (mark@cbosgd).
        !          1731:      If any of you to whom I'm sending this aren't interested in
        !          1732: staying on this mailing list, just let me know.
        !          1733:      Horton replied to an earlier letter by saying he had no idea
        !          1734: when he'd have any time to work on the editor again, so I don't
        !          1735: expect replies from him to this and further such letters in the near
        !          1736: future.
        !          1737:      For those who are not familiar with the subject of item "A."
        !          1738: below, modeline is a feature that he added without publicizing it much,
        !          1739: whereby if any line in the vicinity of the top or bottom of the file
        !          1740: (top and bottom 10 lines?  I don't remember) contains the string
        !          1741: vi: or ex: and then another :, everything between these is
        !          1742: interpreted as a command and executed when this file is read by the
        !          1743: editor.  There was a big squall in net.news when someone discovered
        !          1744: it by chance (an accidental string of this sort occurred in their
        !          1745: /etc/password; fortunately the "command" was meaningless, and evoked
        !          1746: a diagnostic from the editor).  Some serious dangers of this
        !          1747: feature were pointed out by various contributors, one of whom described
        !          1748: for all who were interested how to eliminate it from the source file.
        !          1749: 
        !          1750: Dear Mark,
        !          1751:      Here's another few month's collection of comments...
        !          1752: 
        !          1753: A.  Modeline
        !          1754:      I presume that in following the net.news discussion of the
        !          1755: ``MAJOR BUG (modeline)'' you saw my two contributions; but I'll
        !          1756: summarize the relevant points (not in the order I made them):
        !          1757: 
        !          1758: 1)  One possible feature that would be about as convenient as
        !          1759: the modeline, and would avoid the dangers that people have pointed
        !          1760: out, would be `enhanced tags', in which the 3d entry of a line of the
        !          1761: tags file could be not merely a pattern search, but an arbitrary
        !          1762: command line.
        !          1763: 
        !          1764: 2)  I described (both in net.news and in an earlier letter to you) a
        !          1765: mapping in my EXINIT which makes one keystroke yank the current line
        !          1766: (or the next N lines if preceded by a count) to a named buffer
        !          1767: and then execute that buffer.  If one keeps a set of initializing
        !          1768: commands within a file to which they are to apply, one can then
        !          1769: easily execute them on beginning an editing session, which gives
        !          1770: almost the convenience of the modeline feature, without the dangers,
        !          1771: and has an enormous range of other uses.  So I think the modeline
        !          1772: feature could be dropped.
        !          1773: 
        !          1774:      Let me add to those points:
        !          1775: 
        !          1776: 3)  A modeline
        !          1777:        vi:r %:
        !          1778: leads to an infinite recursion!  Fortunately, ^C cuts it off.
        !          1779: 
        !          1780: 4)  I agree with others' comments in net.news that if the modeline
        !          1781: feature is not dropped altogether, it should be a settable option
        !          1782: with default ``nomodeline''.
        !          1783: 
        !          1784: 5)  It should certainly be off when ``novice'' is set!
        !          1785: 
        !          1786: B.  Tags
        !          1787:      Having mentioned these in point A(1), I will give some other
        !          1788: comments I have:  One of your update documents mentions the fixing
        !          1789: of a bug that left ``nomagic'' set if the file named in the tags
        !          1790: file did not exist.  Very good, but one still ends up with ``nomagic''
        !          1791: if the file exists but the pattern-search is unsuccessful!
        !          1792:      It would also be nice if the tags file could include file addresses
        !          1793: of the form ~user/filename, in particular ~/filename, and if the
        !          1794: command :set tags= recognized the same.  (I suppose this makes no
        !          1795: difference to people who get their tags from ctags, but for me, the
        !          1796: tags file is maintained as a collection of items I have been working on
        !          1797: recently, or mean to soon, and entries are put in or removed by
        !          1798: hand regularly.)
        !          1799: 
        !          1800: C.  Reversal of n and N
        !          1801:      I also mentioned in one of my net.news comments a peculiar behavior
        !          1802: that often seems to occur after I've been using my yank-and-execute
        !          1803: mapping a lot, in which, after a command-line pattern-search :/pattern
        !          1804: (rather than simply /pattern), the screen-mode commands n and N give
        !          1805: searches in the reverse of the expected direction, with ? and /
        !          1806: respectively instead of vice versa.  Perhaps you can figure out what
        !          1807: causes this; if not, would it help for me to do something like make
        !          1808: a core dump of the editor when it is happening and send it to you?
        !          1809: (I don't know how to send a nonascii file, though... .)
        !          1810:      A few more observations on this behavior:  Though I commonly
        !          1811: discover it when I am using my yank-and-execute mapping, it has
        !          1812: happened on at least one occasion when I hadn't use that at all,
        !          1813: so far as I could recall.  It may actually happen quite frequently,
        !          1814: but people just don't notice it because they usually use /pattern
        !          1815: instead of :/pattern.  (My mapping makes it more convenient for
        !          1816: me to use the latter when the pattern is complicated, or I want to
        !          1817: store it for repeated use.)
        !          1818: 
        !          1819: D.  Update on dangerous recursions
        !          1820:      Discovering that ^C interrupted the recursive modeline led me
        !          1821: to test it out on a recursive mapping, :ab x ( x ).  It interrupts
        !          1822: it OK.  Problem solved courtesy of 4.2BSD, I guess.
        !          1823: 
        !          1824:      I will collect under the next heading my usual list of:
        !          1825: 
        !          1826: E.  Minor bugs and modest suggestions
        !          1827: 
        !          1828:      ye and yE yank one character less than they should.
        !          1829: 
        !          1830:      If the command Ne (N a count) would land one on a 1-letter
        !          1831: word, one generally lands at the end of the next word instead
        !          1832: (even if it is also a 1-letter word.  Exception: if one starts
        !          1833: at or after the end of the preceding word, e behaves as it should.)
        !          1834: 
        !          1835:      Note also that in the line
        !          1836:        Sentence... .  Sentence
        !          1837: if the cursor is on the second S, the command ( causes no motion
        !          1838: at all.
        !          1839: 
        !          1840:      I suggest that the motion commands { and } should accept indented
        !          1841: lines as paragraph-starts, or at least that there should be some
        !          1842: way of requesting this in the ":set para=" command.  After all, these
        !          1843: motions shouldn't be useful only to people writing troff files!
        !          1844: 
        !          1845:      In general, the command NC (where N is a count) changes material
        !          1846: from the cursor position to the end of the Nth line, leaving material
        !          1847: before the cursor on the current line unchanged.  But if the line
        !          1848: is indented, and the cursor is on or before the first nonwhite
        !          1849: character, the preceding white text (spaces and tabs) is lost.
        !          1850: 
        !          1851:      It should be possible to use
        !          1852:        :unmap #1       :unmap! #1      :unab #1
        !          1853: when function-keys have been mapped.
        !          1854: 
        !          1855:      Sometimes a noisy phone-line, termcap padding errors, etc.
        !          1856: cause just one or two lines of the screen to be messed up, and one
        !          1857: may only wish to refresh those lines.  Could a command be introduced
        !          1858: which would do this?  Ironically, on a dumb terminal one can generally
        !          1859: do this by moving the cursor over the line, but not on a smart terminal.
        !          1860: Another way one can do it is ddP, but I would sometimes feel uneasy
        !          1861: about unnecessarily modifying the text.  I would
        !          1862: suggest that the form of the command be 1^L (2^L for 2 lines, etc.).
        !          1863: Currently, ^L apparently ignores counts.  (Actually, I'm writing at
        !          1864: the moment on a tvi, so I've verified this for ^R rather than ^L.)
        !          1865: 
        !          1866:      If one uses the source command, and the file sourced contains
        !          1867: a command
        !          1868:        :e newfile
        !          1869: where newfile does not already exist, the diagnostic ``No such file
        !          1870: or directory'' aborts the sourcing process.  One ought to be able to
        !          1871: use such commands in a sourced file.
        !          1872: 
        !          1873:      In vi screen command mode, ^[ is supposed to ``cancel partially
        !          1874: formed commands'' and generally does so without protesting, but if the
        !          1875: partially formed command is a count (e.g., if one has typed 110 instead
        !          1876: of 10 and wishes to start over) it feeps, which depending on one's
        !          1877: terminal can be a minor or a major annoyance.  (Also depending on
        !          1878: whether someone is trying to sleep in the next room.)
        !          1879: 
        !          1880:      The diagnostic, ``First address exceeds second'' should not be
        !          1881: needed with one-address commands!  The case where a series of addresses
        !          1882: before a command, of which the first may exceed the second, is most
        !          1883: useful is when the last address is a pattern-search preceded
        !          1884: by a ";", e.g.
        !          1885:        :$;?^\.PP?-r otherfile
        !          1886: but let me give simpler examples; of the two commands
        !          1887:        :3,1,2ka        :1,3,2ka
        !          1888: the first correctly marks line 2, but the second is aborted by the
        !          1889: diagnostic quoted.
        !          1890: 
        !          1891: F.  A feature that would be very desirable, and might or might not
        !          1892: be easy to implement.
        !          1893: 
        !          1894:      In general, when one is inserting text on a smart terminal in vi,
        !          1895: the context below the text being added is pushed downward, line by line,
        !          1896: till none is left on the screen.  I would like a settable option that
        !          1897: kept a certain number of lines of following context on the screen
        !          1898: during additions.  The point is that one should see the material that
        !          1899: what one is writing will have to mesh with.  What would be involved in
        !          1900: implementing this would, of course, depend on terminal capabilities.
        !          1901: If it would be difficult to keep an arbitrary number of lines,
        !          1902: would it at least be possible to have an option that would keep one
        !          1903: line, using the special bottom-line feature of some terminals?
        !          1904: 
        !          1905: G.  More radical suggestions (wishlist).
        !          1906: 
        !          1907: 1)  Editing text with _u_n_d_e_r_l_i_n_i_n_g.
        !          1908:      Although one of the valuable features of vi is the explicitness
        !          1909: with which most nonprinting characters are shown, this can be annoying
        !          1910: when one wants to deal with text in which many characters
        !          1911: are ``emphasized'' using the sequence _^H; e.g. nroff output.  I
        !          1912: suggest a settable option under which such sequences would be shown as
        !          1913: with ul.
        !          1914:      I realize that this would involve working out a great number
        !          1915: of details, e.g. would motion commands treat _^Hx as one
        !          1916: character or as three?  How would the nth column be defined?  How
        !          1917: would one place the cursor on one of the elements of the string
        !          1918: _^Hx for editing purposes?  What would be done with _^H^A or _^H_^H....?
        !          1919:      I think the best solution would be to treat _^Hx as a single
        !          1920: character for the purposes of motion commands, definition of nth
        !          1921: column, deletions, etc. when this option was set.  In terms of placing
        !          1922: the cursor, two possibilities occur to me.  One would be to only allow
        !          1923: the cursor to sit on the underlined character ``as a whole'', and to
        !          1924: have changes in underlining done by special commands: perhaps ^E as a
        !          1925: toggle to turn emphasis on and off in insert mode, _ to change
        !          1926: underlining in screen command mode as ~ changes capitalization
        !          1927: ("_" is at present a synonym to "^", except
        !          1928: that it takes counts.  ^ could be modified to take
        !          1929: counts, and _ then used as suggested above), and \e in replacement
        !          1930: patterns.  The other would be to consider a cursor sitting ``on''
        !          1931: a sequence _^Hx to actually be on the x, and to set things up so that
        !          1932: if the cursor is on any of the other members of this sequence, the
        !          1933: sequence is ``expanded'' on the screen, i.e. shown as it is in the
        !          1934: present vi.  Then define a single vi command so as not to skip over
        !          1935: the _ and ^H in such a sequence; namely ^H.  (This would mean
        !          1936: making a distinction between h and ^H in screen command mode.)
        !          1937: This one motion would allow one to edit parts of such a sequence.
        !          1938: 
        !          1939: 2)  Editing several files at once.
        !          1940:      When I have to do work that involves more than one file, the
        !          1941: repeated use of :w|e#, yanking text to named buffers to move it, losing
        !          1942: marked lines when I return to a previous file, etc.  becomes
        !          1943: annoying.  I think it would be desirable if one could make a group
        !          1944: of files behave like one file during an editing session, and move
        !          1945: around within that file as comfortably as one move within one file.
        !          1946:      I suggest that visually, each file be separated from the next
        !          1947: by a pattern
        !          1948: :::::::::::::::::::
        !          1949: as when ``more'' is applied to a group of files.
        !          1950: For ``Go to file 3, line 20'' I suggest a screen command syntax
        !          1951: *3*20G.  *-1* and *+2* could mean ``the preceding file'' and ``the
        !          1952: file after next'' in such commands.  (The initial * could be optional
        !          1953: if there is no preceding + or -, as in the first example.)  In a
        !          1954: command such as :w, the default address range would be all of the file
        !          1955: to which the current line belongs (i.e.,
        !          1956: it would be a synonym for :*.*w)  To write all files, I suggest :**w.
        !          1957: :q, :x and ZZ would quit the editing session entirely, while :*1*q
        !          1958: would remove the buffer of file 1 from the object being edited.
        !          1959: On the other hand, relative motions such as 10j, H, etc. would work
        !          1960: within the ``visible object'', the union of the files.
        !          1961: %s/pattern/repl/ would apply to the file containing the current line,
        !          1962: and would have the synonym *.*s/pattern/repl/, while
        !          1963: *1,2,4*s/pattern/repl/ would affect the 3 indicated files, and
        !          1964: **s/pattern/repl/ would affect all files.
        !          1965: 
        !          1966: 3)  Input and output of shell escapes.
        !          1967:      The various commands involving shell escapes that you have
        !          1968: set up allow four possible relations between the text being edited
        !          1969: and the input and output of the commands: none (:!command);
        !          1970: specified line-range as input with output not affecting text
        !          1971: (:address-range w !command); no input from text but output inserted at
        !          1972: specified line (:address r !command); and specified input from text
        !          1973: with output replacing input (:address-range !command).
        !          1974:      It would be nice to have more flexibility; in particular, to
        !          1975: be able to include input from the file and place the output somewhere
        !          1976: else in the file without destroying the input text, and to input
        !          1977: more than one segment of text, e.g.
        !          1978:        !egrep -f[addr.range] [other.addr.range] > [place of insertion]
        !          1979: Obviously, there would be a problem of setting up a syntax that would
        !          1980: avoid confusion with strings that look like address-ranges in the
        !          1981: shell command.  Perhaps \[...\] could enclose address-ranges where
        !          1982: I have used [...] above.
        !          1983: 
        !          1984: 4)  ;
        !          1985:     The ; syntax, allowing one to do a pattern-search starting
        !          1986: from a specified line is useful, but in setting up 2-address commands,
        !          1987: one does not necessarily want the point from which one starts the
        !          1988: search for the second address to be the first address.  If this business
        !          1989: were being set up now, I would suggest that
        !          1990:        address;/pattern/
        !          1991: should simply be a way of specifying the result of doing the indicated
        !          1992: pattern-search relative to the indicated address, so that
        !          1993:        :address1,address2;/pattern/d
        !          1994: would delete from address1 to the location found by the pattern-search
        !          1995: relative to address2.  Since people are used to the existing
        !          1996: syntax of ;, I suggest that some other symbol be used in the above
        !          1997: way, e.g. ], so that
        !          1998:        :address1,address2]/pattern/d
        !          1999: could be interpreted as described.
        !          2000: 
        !          2001: 5) Insertions into long lines on smart terminals at low or medium
        !          2002: baud rate (e.g. 1200).
        !          2003:      This is annoying because the material coming after the point
        !          2004: of insertion begins to wrap around, and the cursor must jump back and
        !          2005: forth, inserting characters at the beginning of the
        !          2006: continuation line, then going back to the point of insertion, and so
        !          2007: on.  (At least, this is my experience on my Z29.  I haven't done
        !          2008: editing by phone connection on any other smart terminal.)  It's
        !          2009: actually nicer on a dumb terminal, where the editor just overwrites,
        !          2010: and shows you the result after you escape.  I suppose that the need
        !          2011: for the cursor to jump back and forth is due to the deficiency of the
        !          2012: terminals -- has anyone suggested to terminal manufacturers that along
        !          2013: with the wraparound feature, they add a feature which ``remembers''
        !          2014: when a line is a continuation of the preceding line, and automatically
        !          2015: pushes material from the preceding line into the continuation line
        !          2016: when characters are added to the former, eliminating the need to send
        !          2017: all these instructions in over a slow line?  (Do terminal manufacturers
        !          2018: listen to editor-software specialists?)  If not, it might just
        !          2019: be best to not show the pushed-over earlier material till the insertion
        !          2020: is complete.
        !          2021: 
        !          2022: 6)  Filename convention
        !          2023:      This is really a suggestion for UNIX generally, but it could be
        !          2024: implemented on the editor separately.  It is that for any file,
        !          2025: filename/.. denote the directory in which the file lies.  (This
        !          2026: does not mean that every file should be treated as a directory, or
        !          2027: that the ls command should show filename/..; it would just
        !          2028: be a convenient way to refer to the directory containing a given
        !          2029: nondirectory file, consistent with the existing convention for
        !          2030: directories.)  Within the editor, the important cases would be
        !          2031: %/.. and #/.., allowing commands such as:
        !          2032:        :1,10w %/../othername
        !          2033: 
        !          2034:                        All for now! Yours,
        !          2035:                                George
        !          2036: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.