Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 v7 ucbtopaz-1.8; site ucbtopaz.CC.Berkeley.ARPA Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!decvax!ucbvax!ucbtopaz!gbergman From: gbergman@ucbtopaz.CC.Berkeley.ARPA Newsgroups: net.text,net.unix-wizards Subject: Re: vi puzzle Message-ID: <557@ucbtopaz.CC.Berkeley.ARPA> Date: Sat, 22-Sep-84 02:12:49 EDT Article-I.D.: ucbtopaz.557 Posted: Sat Sep 22 02:12:49 1984 Date-Received: Wed, 26-Sep-84 06:47:31 EDT References: <545@ucbtopaz.CC.Berkeley.ARPA> Organization: Univ. of Calif., Berkeley CA USA Lines: 128 The question was: if you have set up a vi abbreviation which if executed creates an infinite loop, such as :ab yes yes! or :ab O O'Shaughnessy how can you unabbreviate these, without leaving vi mode or killing the editor? (The reason that these create infinite loops is that an abbreviation consisting of alphanumeric characters is expanded when it is typed in vi insert mode preceded and followed by most any nonalphanumeric characters. In the above abbreviations, the expansion begins with the abbreviation followed by a nonalphanumeric character, and the expansion process is recursive, so this initial segment is again expanded, and so on. The difficulty with unabbreviating them is that bottom-line commands in vi are processed like text-insertions; in particular, abbreviations are expanded. Since the "unabbreviate" command-line is ended with a carriage-return or an escape, which trigger expansion, an attempt to undo these abbreviations gives the same infinite loop.) I know of two types solutions: (1) Create the desired command-line by trickery within the text, then put it someplace from which it can be executed as a command. By what kind of trickery can the command line by created within the text? If you try typing "unab yess" and then backspace over the last "s" and escape, the editor is smart enough to realize that you have typed the word "yes", and will try to expand it. But if you escape after typing "unab yess" and then kill the last "s" with the command "x", or if you type "unab ye" and escape, then append an "s", or in any other way create it using two successive commands, it will not count this as a candidate for expansion, and the desired line can be achieved. To execute this line as a command, my method is to yank or delete it to a named buffer, e.g. with the command "xdd and the execute this buffer using :@x Another way, pointed out by ihnp4!druxp!mab (Alan Bland) -- the only person who submitted a solution to this "puzzle" -- is to write the created command line to a temporary file :.w junk and execute it with the source command :so junk (2) The other method is based on the fact that abbreviation may be inhibited by typing ^V before the following character. Generally speaking, ^V prevents "special" interpretations of a character; in this case it prevents a following nonalphanumeric character from being interpreted as a trigger for abbreviation-expansion. This is not a solution in itself. If you try typing :unab yes and precede your closing carriage-return by a ^V, this will not only prevent it from triggering the expansion, it will also prevent it from executing the command-line; instead, you will get a ^M as part of the command-line. If you hit another carriage return, the line will be executed, but since it now says :unab yes^M and yes^M was never made an abbreviation, the editor will merely report this fact. Likewise, if you type :unab yes and then ^V followed by a space and carriage return, you will get something that looks like the desired line, but in fact it will have a space at the end, and the editor will notice that yes-space was not abbreviated, and so report. However, there is one character which if put in an :unab command line will not in general be interpreted as part of the abbreviation. This is |, which can be used to string bottom-line commands together, e.g. :unab ucb|unab ucla|unab mit|unab hvd Now if you type in the desired line :unab yes, followed by ^V and then by |, and then any other command, for instance the vacuous command, then your desired command :unab yes will be entered and executed. (You might wonder how one can put literal |'s into ab or unab commands. The answer is, by hitting ^V twice before the |. This prevents the special interpretation of ^V and allows it to be included as an actual character in the command line, so that at the next stage, where the command line is processed, it will prevent interpretation of the | as a special symbol. If in fact you wanted to have the effect of a ^V appear when the abbreviation is expanded, you need to hit it four times when executing the command line, while to get a literal ^V in the expansion of an abbreviation, you would have to hit it eight times, resulting in the appearance of four ^V's on your command line, hence two within the abbreviation-output, of which one prevents the special interpretation of the other when this output is output. As another example, suppose you are typing something up to be lpr'd, and you wish to represent the empty set by its conventional abbreviation, an overstruck O and /. You decide to set up an abbreviation whereby typing the word "es" will produce this effect. The correct command-line turns out to be of the form :ab es O*/ where at the point marked *, you hit ^V either 5 or 7 times. I leave it to you to figure out why 5 or 7, but no other counts, will work! There are things about the :ab command that I still don't understand. For instance, I said that the expansion of an abbreviation will be triggered if it is "preceded and followed by "most any nonalphanumeric character" but the actual situation is more complicated. Here are some examples that I have found by trial and error. Perhaps someone who can understand the source code, or who has more patience testing out cases, can tell us the general rule. Of course, what works on the machines I use may not work on yours! Let: s= space, tab, beginning/end of insert, a= alphanumeric *= most nonalphanumerics abbreviation works if c o m m a n d preceded by & followed by s a * s a * :ab ca California + - + + - + :ab x exact + - - + - + :ab 's possessive + + - + - + :ab can't cannot never? :ab & ampersand never? Note that in all these cases, even those I have never been able to make work, the abbreviation is "accepted" in the sense that after the command has been given, the command :ab will show the desired abbreviation among those stored. Have fun! George Bergman Math, UC Berkeley 94720 USA ...!ucbvax!ucbcartan!gbergman