| The vi/ex Editor, Part 9: Take Charge with Macros | |
| Text-Insertion Macros | |
| What These Tools Do | |
| Working Principles | |
| Time for another exercise | |
| Command-Submode Macros | |
| :map Macros | |
| Buffer Macros | |
| :source Macros | |
| Another Exercise | |
| Write and Read Macros | |
| Text-Insertion Macros | |
| As befits an editor with all those built-in metacharacters that | |
| operate while you are typing in text, there are two ways to create | |
| your own macros for use during text insertion. Both can be useful | |
| in the right circumstances, so you'll probably want to put them to | |
| work at times. You may not have a choice -- often the .exrc file | |
| that you may be given when you get a new Unix shell account has | |
| some of these shorthand dodges built in. These two tools have as | |
| many similarities as differences, so I will expound them in | |
| parallel. | |
| What These Tools Do | |
| Both tools act only when you are in text-insertion submode of | |
| screen-editing mode. Nonetheless, the commands that set them up | |
| and manage them are line-mode commands like: | |
| :ab ucb University of California at Berkeley | |
| :map! } Control-[k2cc | |
| The two example lines above will set up two shorthand forms that | |
| you can use without further preliminaries. The first line provides | |
| that whenever you type "ucb" as a separate word in your text, the | |
| editor will replace it with "University of California at Berkeley". | |
| It happens right on the spot, and without any special signal from | |
| you. | |
| The second line is for use if you frequently discover that what you | |
| are typing has become a mess, and that the mess started back on the | |
| previous line. With this shorthand form in effect, whenever there | |
| is a "}" character in what you type in, the editor removes it and | |
| instead acts as if you had typed in "Control-[k2cc". That is, the | |
| Control-[ (generated by the "Escape" key on your keyboard) causes | |
| the editor to escape from text-insertion to command mode, the "k" | |
| causes the cursor to move up a line, and the "2cc" removes both of | |
| the lines involved and puts you back in text-insertion mode, ready | |
| to type in a replacement for those lines and continue on with your | |
| text insertion. As with the previous tool, this happens as soon as | |
| you type in the shorthand form, without any special action by you. | |
| Note that whitespace separates either of these setup commands into | |
| three parts. The first part, from the start of the line up to the | |
| first stretch of whitespace, is just the command name. Part two, | |
| between the first and second stretches of whitespace, is the short | |
| form that you will type into the text. The third part, everything | |
| following the second stretch of whitespace, is what the editor will | |
| insert (and/or execute) when you type in the short form. Only the | |
| first two stretches of whitespace are separators -- any later | |
| stretches are integral components of part three. And whitespace | |
| includes both space characters and tabs, in any mixture. | |
| Working Principles | |
| Now that you've seen what these two tools do, let's consider how | |
| they work: | |
| :abbreviate | |
| (Shortest abbreviation is :ab). This tool acts when you type in a | |
| certain character or string as a separate word, each end bounded by | |
| whitespace, or a punctuation character, or the start or end of a | |
| line, or the start or end of an insertion. As soon as the editor | |
| sees that the abbreviation is a word by itself, it replaces that | |
| abbreviation with the longer word or phrase you have set as | |
| equivalent. | |
| As an example, you might have declared "cat" as your abbreviation | |
| for "felix domesticus". Then, wherever you type in a line such as | |
| "the habits of the common cat include", the editor will promptly | |
| change it to read "the habits of the common felix domesticus | |
| include". But there will be no such change in words that happen to | |
| include the string "cat" in them, such as "catamaran" or | |
| "concatenation". Be careful with this, because while the word | |
| "catlike" will not be changed, the word "cat-like" will be. | |
| Neither a backslash (\) nor a control-V will quote an abbreviation | |
| into a file as itself. Usually, the easiest way to insert an | |
| abbreviation into your text is to escape from text-insertion | |
| submode (back to command submode) in the middle of typing the | |
| abbreviation, then re-enter text-insertion submode and type in the | |
| rest of the abbreviation. If your abbreviation is only one | |
| character long, though, you must fall back on typing the | |
| abbreviation with a letter immediately before or after it, then | |
| returning to command submode to erase the unwanted extra letter. | |
| :map! | |
| (No editor-accepted abbreviation). Very similar to the abbreviation | |
| tool discussed above, but with three major differences: | |
| The shorthand form defined with this command does not need to be | |
| typed into your inserted text as a separate word in order to | |
| operate. Even if it is embedded within another word, the short form | |
| will disappear and its related text will be entered in its place. | |
| This tool does not simply insert the related text into the file, as | |
| the :abbreviate tool does; it acts as though the user had typed in | |
| the related text instead of the short form. That is, if there is | |
| an escape character in the related text, that escape will put the | |
| editor back into command submode, and interpret any following | |
| characters as screen-mode commands. (Unless one of those | |
| characters returns you to text insertion submode -- then characters | |
| following that insert-text command will be all be put into the | |
| file, unless and until there is another escape character.) That | |
| makes accidentally triggering this tool rather dangerous. | |
| Quoting in a character or string that you've defined as a short | |
| form via this command is simple. Type control-V before the | |
| metacharacter, or the first character of the metastring, and into | |
| the text it goes. Even that may not be required if you are dealing | |
| with a metastring, and if the timeout option to the :set command is | |
| still in its default state: turned on. In this case, all you need | |
| to do is be sure that you take more than one full second to type in | |
| the entire metastring, and it will have no meta effect. (This, by | |
| the way, is one reason that this tool's metastrings should be short | |
| -- so you can depend on being able to type one of them in less than | |
| a full second when you do want the metavalue.) | |
| Questions naturally arise regarding these tools. One frequent | |
| query is why anyone would want to mess around with :abbreviate when | |
| it seems much easier to do a general substitution command when the | |
| document is complete. That is, instead of that abbreviation I set | |
| up at the start of this explanation, just run a | |
| :%s/\<ucb\>/University of California at Berkeley/g command | |
| after all the text has been entered. There are several reasons to | |
| use Vi's abbreviation feature instead: | |
| It's not hard to unknowingly type in your abbreviated string where | |
| you don't want it expanded, as in a direct quotation (Savio told | |
| the students, "We don't want ucb to get the upper hand!"), or where | |
| it has an entirely different meaning (Next, punch in the code: aQr | |
| PxN ucb JHt.) Using the substitution command above, you would never | |
| see that these sentences were being disfigured. But with | |
| on-the-spot replacement the mistaken use would be right in your | |
| face. | |
| Lines can get very long when abbreviations are expanded, especially | |
| when there are several abbreviations in one line. When you use a | |
| general substitution command after text entry, there's no way to | |
| know that certain lines have become unreasonably long. But with | |
| the :abbreviate tool, you see the final length of each line as you | |
| go along. And if you use the wrapmargin option to the :set | |
| command, line breaks will generally be inserted after any | |
| abbreviations have been expanded. | |
| It's easy to forget to run a general substitution command. But a | |
| :abbreviate command can be made automatic by putting it in a .exrc | |
| file, and the user can see while typing whether it is or is not in | |
| operation. | |
| This tool can do more than save typing. For example, suppose a | |
| technical writer is in the habit of typing "unix", while company | |
| policy requires "UNIX(R)". Either a general substitution or the | |
| :abbreviate tool will correct that writer's recurring errors, but | |
| only the latter will continuously teach him that "unix" is not to | |
| be used. As another example, consider a writer who begins far too | |
| many sentences with the word "The", which makes for dull reading. A | |
| :ab The DON'T OVERDO IT! command will ensure that every time this | |
| writer types the word "The" at the start of the sentence, it will | |
| promptly be transmuted into the billboard phrase "DON'T OVERDO | |
| IT!", which can be backspaced over to insert a new sentence | |
| beginning. Note that this will not be triggered by words such as | |
| "These" or "Then", nor by the word "the" in the middle of a | |
| sentence. | |
| Another common question concerns precedence of metacharacters. You | |
| can use most of the text-input metacharacters I've discussed | |
| previously as short-form names in :map! commands. Suppose you did | |
| use control-D as such a short form -- what would happen when you | |
| typed control-D at the start of an autoindented line? Would it | |
| wipe out the indentation or type in the phrase that :map! has | |
| associated with it? Or if you used control-H as a short form? | |
| When you subsequently typed a control-H during text entry, would | |
| the cursor back up a space, or would type in a stored phrase? | |
| The answer is that the :map! value would prevail. By preceding | |
| either character with a control-V, you could type in in as itself, | |
| but there would be no way to use the ordinary metavalue of either | |
| character. If you were to map control-D followed immediately by | |
| another control-D or two consecutive control-H characters or any | |
| other doubling of an ordinary metacharacter, the situation would be | |
| more complex. You could then type the two control-D or control-Hs | |
| within one second to get the mapped text typed in, or you could | |
| type control-D or control-H followed by a one-second pause to | |
| invoke the ordinary metavalue. | |
| Time for another exercise. | |
| Suppose that you used control-D or control-H as a short form with | |
| the :abbreviate command. Or suppose that you used some ordinary | |
| character string as both an abbreviation and a mapping short form. | |
| (The editor will allow you to do this.) What would happen when you | |
| typed in this double-use short form during text insertion? This | |
| exercise is straightforward enough that I expect most of you will | |
| find the correct answer before you look at my solution. | |
| Two final warnings. Do not try to define a non-alphanumeric | |
| character or string as a short form with the :abbreviate command. | |
| You probably will be able to do this -- the editor won't object -- | |
| but when you try to use this abbreviation, nothing will happen. | |
| And with either :abbreviate or :map!, do not put any metacharacter | |
| as itself into the long-form string. Even if you manage to get it | |
| into the string as itself, it will not go into your text that way. | |
| What if you have forgotten what short forms you have set up, or are | |
| uncertain as to whether some may have been set up for you via a | |
| .exrc startup file? Well, you can query either tool ju st by | |
| giving its setup command without any arguments. Here are examples | |
| of those queries, with the responses you might receive from the | |
| editor: | |
| :ab | |
| cat cat felix domesticus | |
| wolf wolf canis lupus | |
| :map! | |
| { { ^[o^I^IThe End^[ | |
| } } ^[o^I^I-XXX-^[ | |
| ~ ~ (more to come)^[ | |
| Note that each response line has at least three strings of printing | |
| characters, separated by whitespace. It's that second string in a | |
| line that is the short form; the string that when typed in will be | |
| replaced by the last string shown. (Yes, in every example line | |
| above the first string is identical to the second, but that isn't | |
| always so.) The last string is what will be inserted and/or | |
| executed. | |
| So now you know what characters and strings will have to be quoted | |
| in when you want to insert them as themselves. And if one or more | |
| of those short forms is something you will be typing in so often | |
| that you can't spare the time to quote it in each time you use it, | |
| you can disable the metavalue for the rest of the present editing | |
| session. Just give the command name for the tool that uses this | |
| short form but precede it with "un", and as the only argument give | |
| the short form you want to disable. For example, here are the | |
| commands that will disable the first entry in each of the lists | |
| above: | |
| :unab cat | |
| :unmap! { | |
| Command-Submode Macros | |
| It's common that a text editor has a facility that lets a user | |
| create personalized commands, usually as macros built on existing | |
| commands. The Vi/Ex editor has four such facilities -- something | |
| for every need. While these facilities don't have the low-level | |
| programmability of mock-Lisp, they can accomplish a lot to simplify | |
| your editing, and you don't need to learn a programming language to | |
| use them. | |
| I'll be discussing each facility (or family) in its own section | |
| below, because their structures are quite different. Nonetheless, | |
| you can often combine them to go od effect, by using a macro of one | |
| type to call a macro of a different type. | |
| :map Macros | |
| This is the editor tool that's closest to what most users think of | |
| as a macro facility. It uses the command :map as its setup tool, | |
| and the macros it creates operate when the user is in command | |
| submode of screen-editing mode. Otherwise it works just the way | |
| its very close relative, the :map! tool, works -- which I explained | |
| in depth in the first half of this tutorial part, above. Consider | |
| the three command lines below: | |
| :map v :!wc -w %Control-M | |
| :unmap v | |
| :map | |
| The first line sets up a macro that does a word count on the file I | |
| am editing, as of the last write to storage, whenever I type the | |
| letter v from command submode while I am screen editing. The | |
| second unsets that macro, so that a v command no longer does | |
| anything. The third displays a list of the :map macros that are | |
| currently in effect. All this should be transparently plain to | |
| readers who understand the :map! tool. Still, there are a few | |
| points worth noting that are particularly applicable to the :map | |
| side of the family. | |
| Choosing a short-form for :map macros should not be difficult. | |
| Half a dozen of the printing ASCII characters and many of the | |
| control characters are not used as screen-editing commands or | |
| addresses. Hardly any strings of two duplicate characters (such as | |
| "DD" above) are in use, and most editor versions will let you map | |
| such strings. You don't need to avoid duplicating your :map! short | |
| forms because the name spaces are completely separate. That is, if | |
| you use a particular character or string as a :map short-form and | |
| also as a :map! short-form; for example: | |
| :map }} :!wc -w %Control-M | |
| :map! }} Control-[j0R | |
| there is no conflict. The editor will allow both mappings, and | |
| will use the correct long-form based on the context; whether you | |
| typed }} from command or text-insertion submode. As the first | |
| example above shows, your command string can include any of the | |
| line-mode commands that can be invoked from screen mode, providing | |
| you begin each one with a colon ":" as you would when invoking it | |
| directly while in screen mode, and quote in a Control-M (the RETURN | |
| character) to terminate the command. | |
| Suppose that you ran the two following setup commands, either one | |
| first: | |
| :map Q 2dd | |
| :map V 3jQ | |
| The first command clearly provides that the Q command, which | |
| ordinarily is the command that takes you out of screen mode and | |
| into line mode, does not do that any more. Instead, it now deletes | |
| two lines, and you now have no way to leave screen mode without | |
| unmapping the "Q" character. But what does the new V do? | |
| If you've left the :set command's remap option turned on, its | |
| default value, then the V drops down three lines and then deletes | |
| that third line and the one following. That is, when it comes to | |
| the "Q" character in that mapping, it discovers that "Q" itself has | |
| been mapped, and brings in the mapped value of "Q". But if you had | |
| previously run a :se noremap command, then the editor would not | |
| check for any mappings of the characters within a macro, and would | |
| use the standard meaning of "Q" when it executed the "V" macro. So | |
| then typing a "V" character would move you down three lines and | |
| then put you into line-editing mode. (Yes, that means that while | |
| you would no longer be able to execute the Q as itself directly, | |
| your macros could still access it!) | |
| Buffer Macros | |
| There are limits to the amount of macro text you can store by | |
| mapping it -- not as severe now as with earlier versions of the | |
| editor, but still somewhat confining. To remedy that, the editor | |
| offers a quite-similar tool with practically unlimited storage. It | |
| involves those buffers where you store text pulled from your file, | |
| for later reinsertion at various places. Specifically I mean the | |
| twenty-six buffers named "a" through "z". | |
| From screen-editing command sub-mode, you can type an at-sign "@" | |
| followed by a letter of the alphabet, and the editor will take the | |
| contents of the buffer with that letter-name and execute it as a | |
| screen-mode command string. For example, if you have "0d3w" | |
| (without the quotation marks) stored in named-buffer "k", then | |
| typing @k will delete the first three words on the current line. | |
| After you start using this method in your editing session, there's | |
| an extra added convenience available: typing @@ will repeat the | |
| last such buffer command you ran. | |
| To put a command into a named buffer, get the line or lines of your | |
| command into your file one way or another, then delete or yank them | |
| into the buffer of your choice, as by: | |
| "p3dd | |
| :ya m | |
| to delete a three-line macro into buffer "p" and yank a one-line | |
| macro into buffer "m", respectively. You need not tell the editor | |
| that you regard the contents of a buffer as a command macro until | |
| you choose to execute it with a "@" command. In fact, you can use | |
| a buffer's contents both ways, executing it as a command at one | |
| moment and putting it back into your file as text the next. | |
| One important difference from macros created by mapping: if you | |
| need a linebreak character in a buffer macro, don't try to quote it | |
| in. Instead, type it in the ordinary way, so that it forms a line | |
| break between two lines of your macro text. And don't break a line | |
| in your macro text for any other reason, because the linebreak | |
| characte r that appears there will be treated as a command | |
| character by the editor when you execute the buffer contents as an | |
| editing command string. | |
| :source Macros | |
| Line-mode commands have a macro tool in this editor, too. Of | |
| course you can insert most line-mode commands in the previous two | |
| types of macros, but this tool is dedicated entirely to line-mode | |
| commands, and can include even commands that can't be run | |
| interactively from screen mode via a preceding colon. The only | |
| line-mode commands that can't be run with this tool are the visual | |
| and open commands. With this tool, you set up your macros by | |
| putting their commands into one or more files, then invoke them | |
| with command lines like: | |
| :so /u/myname/commands.1 | |
| Your command files should contain strictly line-mode commands, one | |
| per line unless you separate them within the line by pipe "|" | |
| characters, and should not have a colon before each command. The | |
| other restrictions depend on how you plan to invoke your macro | |
| files. Ideally you should give your source commands while you are | |
| in line mode -- then the above limitations are all you will face. | |
| But if you insist on invoking :source while in screen mode, there | |
| are two other limitations: | |
| Only the first line of your command file will execute. Due to the | |
| editor restriction against running multi-line line-mode commands | |
| while in screen mode, all lines after the first in your command | |
| file will be silently discarded. | |
| If your first command is not complete on the first line (for | |
| instance, an append is not), even that command will not execute. | |
| In this case the failure will not be silent. | |
| Another Exercise. | |
| So if you want to source in command files from within screen mode, | |
| it's a very good idea to create one-line command files. But there | |
| will be a few cases where multi-line command files will be a | |
| worthwhile thing, even when you may be invoking them from screen | |
| mode. Here's an easy exercise for you: come up with a specific | |
| case in which a command file that you may source in from either | |
| line or screen mode should nonetheless have more than one line. Of | |
| course there are multiple possibilities here, so don't be disturbed | |
| if the solution that occurs to you is not one of those I | |
| arbitrarily chose for my answer. | |
| When you really get into sourcing, you'll be pleased to know that | |
| :source files can contain commands to call other :source files. | |
| This is the basis for truly modular editor scripts, and for a raft | |
| of rather tricky maneuvers. It also saves typing when you need to | |
| invoke a source file from screen mode, but the list of commands is | |
| simply too long to fit on one line: a single line in your initial | |
| source file is long enough to call a very large number of other | |
| source files, each with a single long line of commands. You will | |
| probably find that invoking nested :source files from line mode | |
| will turn off line mode's colon prompt, but you can turn it back on | |
| again via a :se prompt command. | |
| Write and Read Macros | |
| The Vi/Ex editor has tools for running some or all of the lines in | |
| the file you're editing through a program outside the editor, then | |
| using the transformed lines to replace the original lines in your | |
| file. It can also run a program with any or no input and insert the | |
| program's output in your file, or write some or all of your file | |
| lines as input to a program that may send its output anywhere. | |
| And where is the macro capability in all this? Well, when you use | |
| these tools you are not limited to standard Unix utilities as your | |
| outside programs -- your own coding will do just as well. Compiled | |
| or scripted, one line or a thousand, in a standard language like C | |
| or Perl or in a specialized one such as Snobol; the rule is that if | |
| your Unix system will execute it, the editor can pass it over your | |
| text. | |
| This tutorial is not going to get into writing these personal text | |
| processors, in any language, so I will only be explaining how to | |
| send your text in and/or out via editor tools. In the examples | |
| below, I will suppose you have a text-processing program named | |
| myhack that lives within your searchpath. | |
| [Editor's note: One external program I use frequently reformats | |
| paragraphs into nicely looking text blocks that are easier to read. | |
| I use the program named reform, published on pages 320-321 in the | |
| first edition of the famous book Programming Perl by Larry Wall and | |
| Randal L. Schwartz. At first blush you may ask, why use such an | |
| external program when I can simply set Vi's wrapmargin variable? | |
| Of course, the answer is how do you easily reform paragraphs that | |
| are already ragged, say due to the problem Walter posed above | |
| (using find and replace to expand abbreviations, instead of | |
| expanding abbreviations using the built-in Vi abbreviation macro | |
| facility?] | |
| Note that the command to execute the outside program should be | |
| typed as you would type it at your shell prompt, because it will be | |
| passed to the shell intact except for the addition of input and/or | |
| output redirection. | |
| If you want to take some (or all) of the lines out of your file, | |
| use them as input to your outside program, then put the resulting | |
| output in place of the original lines, you can use either a | |
| line-mode or a screen-mode command to do it, as shown below: | |
| :196,254 ! myhack -n6 | |
| !L myhack -n6 | |
| 12!! myhack -n6 | |
| !/^CHAPTER/- myhack -n6 | |
| The line-mode command can be invoked from line mode, or from screen | |
| mode by preceding it with a colon. In either case, you give an | |
| address or address range, next the exclamation point, then | |
| everything following until you type return is passed to the shell | |
| as a command line. The line-mode command must have at least one | |
| address because there is no default address for this command. But | |
| the whitespace I show before and after the exclamation point is | |
| permissible but not necessary; I put it in solely for readability. | |
| Screen-mode command form is the exclamation point as the command | |
| name, followed by the target address, then the outside command | |
| (with arguments and/or whitespace as would be required or permitted | |
| on your shell command line), ending when you hit the escape or | |
| return key. As with the c d y commands, you can type two | |
| consecutive exclamation points to send just the current line, and | |
| use a count to send that number of lines as shown in my third | |
| example command. The last example involves an extra escape | |
| character -- at the end of a search pattern address, whether / or ? | |
| based and including any + or - suffix, you must press the escape | |
| key before you start typing the outside command. | |
| You're not limited to just one outside program at a time. You can | |
| pipeline two or more together as your shell permits, ordinarily | |
| with the "|" character. (Because a | character and what follows it | |
| will be passed to the shell, this editor command cannot appear in a | |
| line-mode command string, including a :global string, unless it is | |
| the last command in the string.) The final output of the pipeline | |
| is what will go into your file. And you can undo the effect of the | |
| outside command or pipeline, putting your file back the way it was, | |
| with a u command. | |
| You may not want your text to make a round trip, though. You may | |
| want to send your text, as modified by your outside program, off to | |
| some other destination, or you may want to pull some text into your | |
| file that originated in your outside program, or was taken from | |
| some outside source. In these cases, use the line-mode commands | |
| that appear below: | |
| :1,.w ! myhack -n6 > nufile | |
| :217r ! myhack -n6 < oldfile | |
| The first command above sends the initial lines from the file you | |
| are editing as input to your myhack program, and redirects the | |
| output to a file. It does not erase the affected lines from the | |
| file you are editing. The second runs your myhack program using | |
| the contents of another file as the input, then places the output | |
| in the file you are editing, right after line 217. | |
| Both line-mode commands are shown with addresses, but they are not | |
| necessary. The default address for a :write command is the entire | |
| file; for a :read command, right after the current line. The space | |
| character just before the exclamation-point flag after each command | |
| is absolutely essential; without it you would get something greatly | |
| different from what you expected. | |
| Usually there will be output redirection for the :write ! command, | |
| and input redirection for the :read ! command, but not always. For | |
| example, you may want to :read ! an outside command that generates | |
| a pseudo-random number, using no input at all. When you do need | |
| input or output, you can build the necessary redirection into your | |
| outside program or you can put the redirection on the command line | |
| as shown above, using your own shell's notation. | |
| In The Next Installment of this Tutorial | |
| I'll be putting the techniques I've taught so far to work, showing | |
| how to set up the editor for special purposes. Your suggestions on | |
| what special purposes to consider are welcome, of course. One | |
| purpose that is already in my mind is an arrangement of the editor | |
| for computerphobes: very simple, with beginner features such as | |
| "stateless" editing, and fortified against common user errors. | |
| SIDEBAR: The timeout Function | |
| The :set command's timeout option seems arcane in purpose and | |
| tricky to use, at least to some editor users. But it becomes | |
| pretty plain when you know why and how it actually works. | |
| Basically, when the timeout option is on (its default state) and | |
| you type in a short form you've set up by a :map or :map! command, | |
| you must type the entire short form in no more than one second. If | |
| you miss that deadline, the editor will ignore the metavalue, and | |
| take the characters you've typed at their face value. | |
| This odd requirement serves a purpose; preventing deadlock. As an | |
| example, suppose you have defined "DD" (without the quotation | |
| marks) as a macro via the :map command, and have turned off the | |
| timeout option. Now, while editing, you type a plain D command to | |
| delete part of a line. When the editor receives this single "D" it | |
| is uncertain what to do. Are you actually telling it to delete | |
| that partial line? Or are you starting to type in your double-D | |
| macro? The only way the editor can resolve this question is to | |
| wait and see what character you type in next. But if you are | |
| waiting to see the result of your deletion before you do any more | |
| editing, the mutual wait will last indefinitely. With the timeout | |
| option left turned on, the wait will only be a second or so before | |
| the editor acts on your D command. | |
| One moral of this story is to leave timeout on unless you have a | |
| compelling reason to turn it off, and choose your macro names so | |
| that you can easily type them in within the one-second limit. If | |
| you are not particularly nimble fingered, or if other people may be | |
| using your editor macros, then for practical purposes this means | |
| either a single character or two repetitions of one character as in | |
| my example above. (Some fussy versions of the editor will refuse to | |
| map anything except a single character.) | |
| Another moral is to avoid certain macro names, such as "jj" (again, | |
| without the quotation marks). The standard address j is one that | |
| you might want to type twice in rapid succession, to move directly | |
| down two lines without the trouble of reaching away from the | |
| central keyboard to hit the 2 key. But the user with a macro named | |
| jj had better not move down too quickly via that method, or he/she | |
| will accidentally invoke the macro of that name. | |
| Finally, you should realize that the one-second count before timing | |
| out is not hair-splittingly accurate. The design of the standard | |
| Unix software clock means that the time-out interval may be a | |
| little less or somewhat more than precisely one second. | |
| Solutions | |
| Back to the index |