The vi/ex Editor, Part 4: The Subtle Substitute Command
       
         Making Changes Within Lines
         A Few More Metacharacters
         Replacement-Pattern Metacharacters
         Other Uses for Substitution
         A Start on Script Writing
         Don't Lose Your Files
         Reader Feedback
         The Next Installment
       
       After the :global  command, which we discussed in the previous
       installment of this tutorial series, the :substitute command is
       line mode's most subtle and complex tool.  When I've gone over
       those complexities we'll be ready to deal with techniques and
       tricks of building powerful line-mode command strings.
       
       Making Changes Within Lines
       
       Most of you already know the :substitute 
       command by its shortest abbreviation :s 
       and use it in roughly this form: 
       
         s/previous/former/
         %s/Smith/Lee and Smith/
       
       to make some change within the line you are on, in the first case,
       or change every instance in the file in the second.  If you use
       both forms you are already ahead of the game.  Too many class
       instructors and textbook writers try to tell you that the way to
       change some phrase throughout the file is to type something like:
       
         global/Smith/s//Lee and Smith/
       
       This is wasteful nonsense.  Both forms accomplish exactly the same
       thing, but the second version involves extra typing for you and an
       extra run through the file for your computer.  It does not matter
       that not every line in your file will contain a "Smith" to be
       changed -- the :substitute  command will execute properly in
       either version, and quietly if even one line in the file has a
       "Smith" it can change.
       
       But neither form as it stands  is sure to change every "Smith" in
       the file.  The :substitute command is set up to change only the
       first example of the string it finds on any particular line, so a
       line in the text that originally read:
       
         inure to Smith's benefit only if Smith shall
       
       will be changed by either version of the command to read:
       
         inure to Lee and Smith's benefit only if Smith shall
       
       Line mode has a built-in solution for this problem: place a
       lower-case letter "g" at the very end of the command, immediately
       after the last "/" mark, in order to make the change on every such
       string in each line.  So typing this:
       
         % substitute /Smith/Lee and Smith/g
       
       will make that text line come out as:
       
         inure to Lee and Smith's benefit only if Lee and Smith shall
       
       Finer tuning of the instances can be done by a little trickery.
       Suppose you are working on tables, and want to change only the
       very last "k37" on each line to "q53". This command will do it:
       
         % substitute /\(..*\)k37/\1q53
       
       If this seems surprising, remember that in a search pattern with a
       wild card, the editor always extends the match to the greatest
       length it can.  In this case that means the string starting at the
       beginning of the line and ending with the last "k37" in the line.
       
       Now you should be able to extend this example.  What command would
       change only the second-to-last "k37" on each line?  This requires
       a shrewd guess from you, so I've written a solution you can
       compare to your own.
       
       A Few More Metacharacters
       
       You probably already know that you don't always have to type the
       search pattern that indicates the text to be replaced by a
       substitution command.  If you want to reuse your very last search
       pattern, whether that was in a substitution command or not, you
       can use an empty search pattern string to stand for the last
       search pattern, so the two commands below are actually identical.
       
         /Murphy/ substitute /Murphy/Thatcher/
         /Murphy/ substitute //Thatcher/
       
       Either command will go to the next line containing "Murphy" and
       there replace the first "Murphy" with "Thatcher".
       
       Within a substitution command's search pattern to find the text to
       be removed, all the normal search-pattern metacharacters apply.
       So do two more that are reserved only for substitution commands:
       the "\(" and "\)" metacharacters.
       
       These two metacharacters don't match anything themselves, so:
       
         substitute /^The cat and small dog show/
         substitute /^The \(cat\) and \(small dog\) show/
       
       are exactly the same command as far as they go.  But the
       substitution command remembers what it finds to match the text
       between a pair of "\(" and "\)" metacharacters, for use in the
       replacement text.  Whenever your replacement pattern contains "\1"
       the editor replaces that metacharacter with whatever matched the
       characters that were between the first pair of "\(" and "\)"
       metacharacters.  A "\2" in the replacement pattern is removed and
       replaced by whatever was matched the characters between the second
       pair.  And so on -- you can have up to nine pairs in one
       substitution command.  These metacharacter pairs can even be
       nested in the to-be-replaced text; the one that starts first will
       be represented by "\1" and so on.  So if you extend that second
       substitution command above to read:
       
         substitute /^The \(cat\) and \(small dog\) show/My \2-\1 fair
       
       the substitution command will produce a line that begins: 
       
         My small dog-cat fair
       
       Or if you type:
       
         substitute :up \(and \)\(over \)\(the sky\):\2\1\2\1\2\3
       
       then your command will change the first line below to read as the
       second line, just beneath it: 
       
         up and over the sky
         over and over and over the sky
       
       (I used the colon ":" character to separate the parts of the
       command, instead of the slash "/" character, solely to make it
       more readable for you.  There is no danger of the editor confusing
       "/" with "\" or "l" (el) with "1" (one) etcetera.)
       
       As the preceding examples show, the "\(" and "\)" are not too
       useful with plain-text search patterns; about their only real
       value there is when you are searching for something that's
       difficult to spell correctly, and don't want to type it into the
       replacement pattern with possible spelling errors.  (Spelling
       errors aren't so dangerous in the to-be-replaced text, because
       they only cause the pattern match to fail.)
       
       These metacharacters save the day, though, when you are dealing
       with other search metacharacters in searching for text that you
       will want to put back in.  (Often the only way to specify the
       exact spot you want the replacement done is to include some
       neighboring text in the search pattern, and tell the editor that
       after the neighboring text has been taken out it is to be put back
       in right where it was.)  Here are three examples of this kind of
       substitution:
       
         % substitute :\([Ss]ection\) \([0-9][0-9]*\):\1 No. \2:g
         /\([Ss]ection\) \([0-9][0-9]*\)/ substitute ::\1 No. \2
         % substitute ,[Aa]nswer: \([TtFf] \),ANSWER: \1,g
       
       The first of these simply inserts "No."  in the middle of phrases
       that are section numbers, throughout the document.  But the "\("
       and "\)" notation is essential to preserve the section number in
       each case, and also to leave unchanged the capitalization or
       noncapitalization of the first letter of "section".
       
       The second command does the same thing, but only on the very next
       line that has a section number to change.  The surprise here is
       that I put the "\(" and "\)" in the address pattern to find the
       correct line. A line address doesn't use these metacharacters, of
       course, but it does not object to them, either.  It just ignores
       them in its own line search, but does pass them along when a
       following substitution command reuses the last search pattern, as
       happens in this example.
       
       The third example is useful in editing a list of answers to
       exercises. It stops at each answer to a true-or-false question and
       capitalizes the entire word "answer". The innovative aspect of
       this command is that it finds the letter "T" or "t" or "F" or "f"
       following the word "answer", so it will not change the
       capitalization where an answer is numerical rather than true or
       false.  And yet, the letter indicating whether "true" or "false"
       is the correct answer is not discarded as a side effect.  This is
       primarily an example of a change that can be done more simply by
       using other metacharacters in the replacement pattern. Those other
       metacharacters are described below.
       
       Replacement-Pattern Metacharacters
       
       The string of characters you want to put in via a substitution
       command can use its own list of metacharacters.  They're entirely
       different from the metacharacters used in searching for a pattern
       you want to take out of a line.
       
       &
       
         In a replacement pattern, the "&" stands for the entire text
         that was to be replaced.  Use this when you want to add rather
         than replace text.  For example, to change "kit" to "kit and
         kaboodle" regardless of whether "kit" is capitalized, use:
       
           % substitute /[Kk]it/& and kaboodle/g
       
         If you have magic turned off, you must backslash the "&" to give
         it metavalue.  With magic  on, backslash an "&" to insert it as
         a regular character. (See the explanation of set in the
         subsequent article).
       
       ~
       
         The "~" character represents the replacement pattern you used in
         your last substitution command.  One good use for this is in
         correcting various misspellings of a single word: 
       
           % substitute /[Ff]anstock clip/Fahnestock clip/g
           % substitute /[Ff]ahnstock clip/~/g
           % substitute /[Ff]ahnstocke clip/~/g
           % substitute /[Ff]annstock clip/~/g
           % substitute /[Ff]anestock clip/~/g
           % substitute /[Ff]aenstock clip/~/g
       
         If you have magic turned off, you must backslash the "~" to give
         it metavalue.  With magic on, backslash a "~" to insert it as a
         regular character.
       
       \U
       
         A "\U" metacharacter makes all letters following it into
         capitals; to the end of the replacement pattern or until another
         metacharacter turns it off.  Here's how you'd use it to change a
         section of your document to all capitals:
       
           1 , substitute /.*/\U&
       
       \L
       
         A "\L" gives the opposite effect of a "\U"; all following
         letters become lower case.  You might use this to decapitalize
         acronyms:
       
           % substitute /FORTRAN and COBOL/\L&/g
       
       \E
       
         Use "\E" to end the effect of a "\U" or "\L" metacharacter.
         Everything following the "\E" has the same mix of capitalization
         as originally.  For example, to enclose a line of text in curly
         braces, and also change just the first word to all capitals: 
       
           substitute :\([^ ]*\)\(.*\):{\U\1\E\2}
       
         No "\E" is needed when you switch from "\U" to "\L" in the
         middle of a replacement pattern, or vice versa.  When either of
         those metacharacters appears, it automatically ends the effect
         of the other. So if you have a list of book titles, one title
         per line, with only the first letters of the words capitalized,
         and you want to change those titles to all capitals before the
         colon in the middle of each title, and all lower case after it,
         just type: 
       
           % substitute ,\(.*\):\(.*\),\U\1:\L\2
       
       \u
       
         This metacharacter capitalizes just the single letter that
         immediately follows it.  If the character that immediately
         follows it is not an alphabet letter, "\u" does nothing.
       
       \l
       
         The same as "\u", except that "\l" makes the immediately
         following letter come out as lower case.
       
       One more thing that's important to know about reusing patterns in
       substitution commands.  When all or part of a text-to-be-replaced
       pattern is going to be used as a replacement pattern, or vice
       versa, the command reuses the result of the original pattern,
       after all the metacharacters have been evaluated in the original
       situation.  Since the metacharacters in either of those two types
       of patterns have no meaning in the other type, it could hardly be
       otherwise.
       
       But when the reuse involves a text-to-be-replaced pattern being
       used a second time as a text-to-be-replaced pattern, or a
       replacement pattern being reused as a replacement pattern, the
       command brings along all the original metacharacters and evaluates
       them afresh in the new situation.  Thus, in either of the cases in
       this paragraph, the second use is unlikely to produce exactly the
       same results as the first use did.
       
       Now another exercise for you.  Suppose that lines 237 through 289
       of a file have unknown capitalization--any line could be all caps,
       all lower case, or some mixture.  These lines are to be changed so
       that the first letter of every word is a capital and all other
       letters are lower case.  To simplify this, words are separated by
       space characters.  What is the easy way to do this with one
       line-mode substitution command?  This exercise depends on
       something I did not state directly, so don't feel bad if my
       solution is a little simpler than yours.
       
       Other Uses for Substitution
       
       Despite the name, the :substitute command doesn't always take
       something out of the line and put something else in its place.
       Here's an example that adds text at the start of certain lines
       without removing anything: 
       
         537 , 542 substitute /^/WARNING:  /
       
       so that text which originally looked like this:
       
         The primary output line carries very high voltage, which does not
         immediately dissipate when power to the system is turned off.
         Therefore, after turning off the system and disconnecting the
         power cord, discharge the primary output line to ground before
         servicing the output section.
       
       now looks like this:
       
         WARNING:  The primary output line carries very high voltage,
         WARNING:  which does not immediately dissipate when power to
         WARNING:  the system is turned off.  Therefore, after turning
         WARNING:  off the system and disconnecting the power cord,
         WARNING:  discharge the primary output line to ground before
         WARNING:  servicing the output section.
       
       It's just as practical to pull some text out of lines without
       putting anything back in its place.  Here are two command lines
       that do just that: 
       
         % substitute / uh,//g
         . , $ substitute / *$
       
       The latter command removes superfluous spaces at the ends of
       lines. It doesn't need the final two slashes because there is no
       suffix to be distinguished from a replacement pattern.
       
       At times you might use both the previous principles, to create
       :substitute commands that neither subtract nor add any text.
       Sound pointless?  Here's one such that I sometimes use when I'm
       well along in writing one of these tutorials: 
       
         % substitute /^$
       
       Now here's a different kind of exercise for you.  I've already
       given you the command, above.  It obviously makes no change
       whatsoever in the file.  So why do I run this command?  You need a
       goodly dose of inspiration to answer this, so don't be embarrassed
       if you have to look at my answer to this one.
       
       A Start on Script Writing
       
       Already you know enough about the editor to be able to plan some
       fairly complex edits.  Here's a short introduction to the art of
       writing editing scripts for this editor.
       
       BOTTOM-UP PROGRAMMING. That's usually the best way to build a
       complex editor command or command script.  That's a programmer's
       term that means putting all the little details in separately and
       then pulling them all together into a unified whole, rather than
       starting with a grand overall plan and forcing the details to fit.
       
       For example, reader R.T. of San Francisco, California asks how to
       use the editor to automatically add HTML paragraph tags to each
       paragraph of manuscripts.  This requires inserting the string
       "" at the start of the first line of each paragraph, and
       the string "" at the end of the last line.  In these
       manuscripts, a completely empty line (not even a non-printing
       character on it) separates one paragraph from another.
       
       This looks pretty easy.  All that seems to be needed is to go to
       each empty line, then move up to the preceding line to insert the
       end-of-paragraph string and down to the following line to put in
       the start-of-paragraph string.  But there are flaws in the obvious
       command to do this:
       
         global /^$/ - substitute :$:: | ++ substitute /^//
       
       The first problem is that when the editor goes to the empty first
       line that commonly begins a file, it will be unable to move up a
       line to do the first substitution.  No substitution is needed
       there, of course, but since the editor doesn't leave that empty
       first line, moving down two lines will put it on the second line
       of the following paragraph -- definitely the wrong place for a
       start-of-paragraph tag.  There are several ways to fix this
       problem:
       
       Have the editor :mark the empty line before leaving it to execute
       (or attempt to execute) the first substitution.  Then it can go to
       the marked line (which works even if the editor never left it) and
       drop down one line to perform the second substitution.
       
       Change the address of that second substitution command from "++"
       to "/./" in order to move forward to the next nonempty line, which
       will be the first line of the following paragraph whether the
       search starts from the empty line or the line above it.
       
       Run two separate :global searches, each of which executes one of
       the two substitution commands.
       
       Problem number two is that there may be several empty lines
       between two paragraphs, since HTML interpretation is not affected
       by them. If the editor is on the first of two or more consecutive
       empty lines, the command I first proposed above will perform its
       second substitution on the second empty line just below it.  When
       it moves to the second previously-empty line, it will run the
       first substitution co mmand on the empty line it just left.  (Yes,
       the second line is no longer empty, but it has already been marked
       by the :global command before any substitutions are done.)  That
       is, a stretch of text that initially looked like this:
       
         at this meeting, so be sure to be there!
       
         At next month's meeting we'll hear from the new
       
       and should have been edited to look like this:
       
         at this meeting, so be sure to be there!
       
         At next month's meeting we'll hear from the new
       
       actually turns out like this:
       
         at this meeting, so be sure to be there!
         
         
         At next month's meeting we'll hear from the new
       
       It may look as though this hazard can be defeated by modifying the
       number two solution to the first problem above.  That is, the
       address for both substitutions will be a search pattern that looks
       for a line that already has some text on it.  This works properly
       when the editor is on the first of two consecutive empty lines.
       From the second line, though, it runs its substitution commands on
       lines that have already been given their tags, so the sample text
       now looks like this: 
       
         at this meeting, so be sure to be there!
       
         At next month's meeting we'll hear from the new
       
       COMPLEX CONDITIONALS. What's really needed here is
       double-conditional execution.  That is, substitution commands must
       run on a given line only if both of these conditions are true:
       
         - The line to be substituted is adjacent to the empty line.
       
         - The line to be substituted is not itself empty.
       
       In this case, the editor can handle it.  The :global portion of
       the command line takes care of the first condition if the
       substitution commands' addresses move exactly one line in each
       direction from the empty line.  (Of the three proposed solutions
       to the first difficulty encountered, numbers one and three both do
       this much.)  To satisfy the second condition, make the
       substitution commands remove one character from the existing line
       -- and then replace it, of course.  This ensures that if there is
       no character to remove because the line is empty, the substitution
       command will fail on that line and do nothing.
       
       Either the first or third solution can be adapted to satisfy that
       second condition.  I've used the third solution in the example
       commands below, because the technique is easier to follow than it
       would be with the first solution:
       
         global /^$/ + substitute /^./&/
         global /^$/ - substitute :.$:&:
       
       Bottom-up techniques can be continued if there are yet other
       special needs to be accommodated.  Reader R.T. may have headlines
       and subheads mixed in with the paragraphs, and may already have
       appropriate HTML tags at the beginnings and ends of those heads
       and subheads.  As an exercise, how would you adapt the commands
       just above so they would not add a paragraph tag where any text
       already begins or ends with an HTML tag?  Hint -- an HTML tag
       always begins with a "" character. This is a
       very minor change, so you probably will not need to look at my
       solution except to confirm your own answer.
       
       A LITTLE TRICKERY. At times a command needs to be supercharged by
       way of a far out use of substitution--something perfectly
       legitimate, but never intended by the people who wrote this
       editor. Here are a few that you may find useful.  
       
       You can't make a substitution that extends over more than a single
       line--not directly, that is.  Any attempt to put a "newline"
       character in either the to-be-replaced pattern or the replacement
       pattern of a substitution command will fail. But by combining the
       global and substitute commands, you can often get the effect of a
       substitution that spills over a line ending.
       
       Let's suppose that you have to alter a long document so that all
       references to "Acme Distributors" are changed to "Barrett and
       Sons". A simple substitution command will make most of these
       changes, but it will miss those instances where "Acme" appears at
       the end of one line and the next line starts with "Distributors".
       A followup pair of substitutions, to replace "Acme" wherever it
       appears at the end of a line and to replace "Distributors" when it
       starts a line, would wreak havoc--this document also refers to
       "Acme Supply Co." and to three other companies whose names end
       with "Distributors".
       
       But we can handle this problem nicely with the following two
       command strings:
       
         global /Acme$/ + substitute /^Distributors/and Sons
         global /^and Sons/ - substitute /Acme$/Barrett
       
       The first command goes to every line that ends with "Acme" and
       then moves forward one line--if and only if that next line begins
       with "Distributors", it is changed to begin with "and Sons". The
       next command reverses the process to change "Acme" to "Barrett",
       but only in the right instances.  (Note well that the second
       command searches for "and Sons", not "Distributors", because the
       first command has changed those line-split "Acme Distributors" to
       "Acme and Sons".)
       
       Often it is a good strategy to start with a change you definitely
       don't want in order to wind up with what you do want.  Suppose you
       are a technical writer who has just finished writing a number of
       lengthy photo captions full of phrases like "the light spot in the
       upper righthand corner" and "dark areas near the lower lefthand
       edge". Along comes the news that the Art Director has decided to
       flop all the photos: print them in mirror-image form.  Suddenly,
       everything that was on the right is now on the left, and vice
       versa.
       
       Your captions will be accurate again if you change every
       "lefthand" to read "righthand" and vice versa.  But how to do that
       without wading through the whole text and making each change
       individually?  The obvious pair of substitutions will not work:
       
         % substitute /lefthand/righthand/g
         % substitute /righthand/lefthand/g
       
       The second command doesn't just change the original instances of
       "righthand" to "lefthand"; it also reverses every change your
       first command made--now everything is described as being on the
       lefthand side. But the following three substitution commands will
       do the job nicely.
       
         % substitute /lefthand/QQQQ/g
         % substitute /righthand/lefthand/g
         % substitute /QQQQ/righthand/g
       
       By making the first command change "lefthand" temporarily to
       "QQQQ" (or any other string you know will not be found in your
       document), you keep those changes safe from the effect of your
       second command.  Then, after that second command has finished, the
       third command changes those Q strings to what you had wanted in
       the first place.
       
       It can even make sense to type in things incorrectly, then change
       them to what you want via substitution.  When I'm writing
       documents in plain ASCII, to be printed without any formatting, I
       often use a line across the page to separate major sections of the
       document.  But where others are satisfied with just a string of
       hyphens, or another single character, I pretty things up with
       multicharacter dividers like:
       
       -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
       -+--+--+--+--+--+--+--+--+--+-
       *~*~*~*~*~*~*~*~*~*~*~*~*~*~*~
       [][][][][][][][][][][][][][][]
       
       Not that I have the patience and concentration to type in
       page-wide lines of alternating characters, especially when I would
       have to constantly get on and off the shift key, too.  No, I just
       use my repeat key to fill the line with whatever character will
       begin my eventual multicharacter pattern.  For those four patterns
       above, I would have repeat-keyed in these four lines, respectively:
       
       ------------------------------
       ------------------------------
       ******************************
       [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
       
       Then I only have to run a simple repeated substitution to get the
       line I actually want.  Here are the commands I would run on the
       four lines above, respectively:
       
         substitute /--/-=/g
         substitute /---/-+-/g
         substitute /\*\*/*\~/g
         substitute /\[\[/[]/g
       
       SEMI-AUTOMATIC SUBSTITUTIONS.  At times you'll have to make
       changes that are so dependent on human judgment that no
       substitution tricks could possibly do exactly what's wanted.  In
       those cases there are two ways to have the editor partially
       automate those changes.  
       
       The first is to use a variant form of the substitute command that
       presents each potential substitution on your screen, and asks you
       to accept or reject it.  All you need to do is put a lower-case
       "c" at the end of your substitution command, in the same place you
       would put a "g" to change every instance on each line, like either
       of these examples: 
       
         % substitute /^something/something else/c
         % substitute /something/something else/gc
       
       The editor will then display the lines where substitutions are to
       be made on your screen, one at a time.  Each line will have "^"
       marks below the text to be removed, like this: 
       
         something in the air.  The consensus is that
         ^^^^^^^^^
       
       and if there are two or more places on the line where the
       substitution could be performed, the line will be displayed on
       your screen two or more times, with a different potential
       substitution marked each time. After displaying a line on your
       screen, the editor will wait for you to type something ending with
       a carriage return.  If whatever you type begins with a lower-case
       "y", the change will be made.  If it begins with anything else,
       the text will be left as it is.  
       
       Even this substitution variant may not give you enough control.
       You may need to see more than one line to verify your judgment, or
       the text to be put in may vary from one place to another.  In
       those cases, you can use one of the qualities of the :global
       command.  This is a simplified version of the technique our
       programmer friend Hal (in the first installment of this tutorial)
       used to work over the problem points that Lint found in the code
       he was updating.
       
       If you are editing in screen mode, as usual, you must start by
       typing a capital "Q" to go into line mode.  From line mode's colon
       prompt, give a command like the following (if you want to make the
       same substitution as in our previous examples):
       
         global /something/ visual
       
       This command will bring you in turn to each line in the file that
       contains the string "something" and put you in screen-editing mode
       there.  After you've looked around, and made a substitution if you
       think it justified, typing a capital "Q" takes you out of
       screen-editing mode and returns you to the global command, which
       takes you the next marked line and resumes screen editing.
       
       There is an indirect hazard in leaving screen editing mode,
       though.  And that brings us to the whole dismal subject of
       preventing loss of your changes, or of your entire file, while you
       are in the editor.
       
       Don't Lose Your Files 
       
       The vi/ex editor is not strong on protecting you from the
       consequences of your own mistakes.  In part that's just the
       natural result of giving you a lot of editing power.  But when it
       comes to losing all the changes you've made in a file during a
       session, or even losing the original file you started with, the
       editor could be a lot more responsible without hamstringing your
       subtle edits.  Still, there are ways you can comfortably protect
       yourself from those hazards, and many of those ways I explain
       below.
       
       IN EMERGENCIES. Consider one of the editor's safety features that
       can accidentally but quite easily turn into a disaster. You may
       already know that when you edit with this editor, you are working
       on a copy of the file, not the original.  Your changes do not
       affect the original unless you use the :write command, for which
       :w is the shortest abbreviation, or leave the editor in a normal
       way.  That's a good precaution against making a mistake with this
       powerful editor that mangles your file, and then discovering you
       have no backup copy.
       
       That copy you are working on lives in a volatile place, though,
       where it can easily be erased when the system crashes or your link
       into the system goes down.  That could cost you all the additions
       and changes you'd made in that session with the editor.  Your
       first line of defense against this is to run the :write command
       often--every time you run it, your current edited version replaces
       the previous version in the stable permanent-storage area on disk.  
       
       And if you don't intend to change the original?  Your edited
       version is to be a new file, with the original left untouched?
       Well, you can use a modified form of writing the file, by typing
       :write nufile where "nufile" is whatever you want the name of the
       edited file to be.  (That can be a path name, in case you don't
       want to put the new file in your current directory.)  This will
       write the revised version only to the new file (creating the file
       if necessary), and leave the original file untouched.
       
       That method of preserving the original file is dangerous, though.
       If you forget even once to add the filename to the :write command,
       your original file is wiped off the disk.  That's why this
       technique is best reserved for occasions where you do want to
       change the original file, but also want a copy of some partially
       edited stage of the file saved elsewhere.  When you get the file
       to the state you want to save as a copy, run both of these
       commands:
       
         write nufile
         write
       
       and then go back to editing and writing to the file as usual.
       
       The sane way to protect your original file from any changes is to
       start your editing with a :file nufile  command, for which :f
       nufile  is the shortest abbreviation. From that point on, the
       editor considers "nufile" to be the name of the file you are
       working on, and writes go automatically to that filename.
       (Incidentally, if you ever forget whether you have changed the
       file name, or what you've changed it to, a :file command by
       itself, without a file name, will tell you what the editor thinks
       the file's current name is, among other interesting facts.)  
       
       CRASHES WILL HAPPEN. Still, a crash may catch you by surprise,
       with a lot of additions and changes that you have not written to
       any file.  To protect against this, the editor always attempts to
       save your current working copy of the file when a crash is
       imminent.  You can even launch an emergency save yourself when you
       face a sticky situation, such as being unable to do a normal write
       because it would exceed your filespace quota.  Just type a
       :preserve command (or its :pre abbreviation) and the working copy
       is normally preserved.  There are a few gotchas to watch for,
       though.
       
       The preservation function puts the saved copy in a specific
       directory, and it will fail if that directory does not exist or is
       not writable.  (The path name of that directory varies between
       versions of the editor, although /var/preserve seems to be a
       common choice on modern Unix systems.)  To check writability, run
       a :preserve command from a short file, as a test.  If the result
       is a message something like this:
       
         Can't open /var/preserve
         Preserve failed!
       
       there is a problem you will have to take up with your system
       administrator.  (To speed up that discussion, bring along the path
       name of the directory that couldn't be opened.)  If the message
       reads like this:
       
         File preserved.
       
       so far, so good.  The next question is whether the editor has
       preserved an accurate copy or a pile of garbage--some editor
       implementations are broken in this area.  To check this, recover
       the file you've just preserved.
       
       RESCUING SAVED FILES. There are two ways to recover a rescued
       working copy, whether it was saved in a crash or because you used
       the :preserve command.  Usually you recover it from your shell
       command line, by entering the editor with a "-r" flag:
       
         vi -r novel.chap3
         vi -r
       
       The first of these commands puts you in the editor, with the
       latest rescued copy of your file "novel.chap3" before you.  The
       latter command doesn't put you in the editor at all; it displays a
       list of all files that have been emergency-saved and then returns
       you to the shell command line. This list is useful when, say, the
       system crashed while you were editing a file that you hadn't given
       a name.  (Yes, you can enter the editor without giving a filename
       to edit; the editor will simply bring up an empty buffer and
       assume you will give it a name later.)  In this case the
       preservation process will give the file a name, and you must know
       this name to recover it.
       
       I said that the first command would bring up the latest rescued
       copy of the file you named.  If the system has been staggering for
       a while, there may be more than one occasion when either you or
       the system caused the editor to preserve the working copy of that
       file. If the latest version is not the best copy, you can discard
       it and pull up the next most recent version, without leaving the
       editor. Just give a :recover command (or its :rec abbreviation) to
       have the current rescued version discarded and replaced by the
       next-latest of the saved copies.  (When you're already in the
       editor, there's no need to give the name of the file to recover if
       it is the same as that of the file you're editing at the time.
       The editor assumes the current filename unless you give another
       name as an argument following the :recover command.)  If this
       isn't the best copy either, you can continue this process.
       
       When you've recovered a file either way, look it over.  If the
       editor version you're using has a broken preservation function,
       you'll only find garbage characters or a display like this:
       
         LOST
         LOST
         LOST
         LOST
         LOST
       
       If that be the case, the file you preserved is hopelessly lost and
       you'd better have a talk with your system administrator about
       getting a better version of the editor.  But if what you see looks
       like what you had, then all you have to do is write the copy
       you've recovered to a file somewhere--the preserved copy was
       erased when you used one of the recovery commands, so it can't be
       recovered that way again.
       
       And that brings up the last gotcha.  You may believe that any of
       the three commands ZZ or :x or :wq will check whether the working
       copy needs to be written to the file, write it only if necessary,
       and then quit the editor.  Actually, the last of the three, the
       :wq command, always writes to the file regardless, and is the only
       one you should use.
       
       The first two attempt some checking, but their checks are not very
       complete.  In particular, they and the :quit command often check
       for nothing more than the flag that is set when an editing change
       is made to the current working copy and unset when the working
       copy is written to the file.  You are courting disaster if you
       ever use the ZZ or :x commands, or if you use :quit carelessly.
       
       The gotcha in the case of a recovered file is that pulling a new
       file into the buffer, whether normally or by recovering an
       emergency-saved copy, is not an editing change.  If your version
       of the editor has a weak version of ZZ or :x then its casual check
       will show no reason to write the file, and all your carefully
       recovered work will be lost for good when the command closes the
       editor without writing the file.  So always use :wq or separate
       :write and :quit commands to end an editing session.
       
       A FEW MORE HAZARDS AND SOLUTIONS. Worse yet can befall you.  You
       may accidentally lose both your own editing changes and the
       original file you were working from.
       
       Suppose one of your global editing commands went astray and
       trashed your working copy of the file, but didn't happen to affect
       the part that is on your screen.  If you then wrote the working
       copy to the file, the garbage replaced your original file
       contents.  Oh, misery!  And with any but the smallest file, it's
       not practical to look over the working copy carefully before each
       :write command.
       
       Or perhaps you did discover the disaster before you wrote the
       working copy to the file.  Seeing that undoing the errors was not
       feasible, you decided either to run an :edit! command to bring up
       a fresh copy of the original file, or a :quit!  to leave the
       editor.  In either case, the "!" at the end of the command tells
       the editor to ignore the garbage changes that have not been
       written to the file.
       
       But since you were not creating an editor script here, you
       probably typed the short form of your command, either :e! or :q!.
       At least you tried to.  Perilously placed between the "e" and "q"
       keys on a standard keyboard is the "w" key.  If you accidentally
       typed :w! instead of what you intended, you told the editor to
       overwrite the original file with that trashed version, and ignore
       any anti-write protections you may have set.  Oh, misery cubed!
       
       You are not lost yet, though, if you have been editing along in
       screen mode all the while.  At any time you can type a short
       sequence to put the working copy back the way it was when you
       started this editing session. Then you only need to write the
       working copy to the file to expunge the trash there.
       
       Start by typing Q to leave screen mode and drop back to line mode.
       Now, line mode has an undo command that works the way the screen
       mode u command does, but on line mode commands.  That is, it
       reverses the effect of the latest line mode command that changed
       (or may have changed) the working copy.  One line mode command
       that may well change the working copy is visual, of course. And --
       surprise -- when you typed vi novel.chap3 from your shell prompt
       to enter the editor, your shell actually launched ex (for which vi
       is just an alias) and the editor gave itself an initial visual
       command to boost you into screen mode.
       
       So all the time you've been editing, the editor has been holding a
       complete copy of the original file, in case you go back to line
       mode and want to reverse the effect of that initial visual
       command.  (That's one reason the editor's buffer takes up so much
       more room than you'd expect in swap space.)  If you want to see
       the complete command sequence to restore the original working copy
       and return to visual mode, using shortest abbreviations and
       showing carriage returns as new lines, here it is:
       
         Qu
         w
         vi
       
       One last hazard, which may seem childish to experienced Unix users
       but trips up many a refugee from single user systems.  Unless
       you're on one of those rare Unix implementations that offers file
       locking, there is little to prevent another user on the system
       from editing the same file at the same time as you do.
       
       You will each be editing on a separate working copy, so there will
       be nothing to tell you that someone else is also editing the same
       file.  But each time you write your changed version to the file,
       you will wipe out whatever changes the other user has already
       written to file, and vice versa.  The ultimate victor in this
       unknowing war will be the user who finishes editing last. The
       other user can come back an hour later and find no indication that
       he/she ever touched the file.
       
       There's no real technical solution to this danger.  You'll just
       have to coordinate carefully with other users on files that more
       than one of you may have occasion to edit.
       
       Reader Feedback
       
       One of our readers  raised a significant point about this
       technique; important enough to deserve a reply published in this
       article.
       
         Dear Walter...
       
         In your tutorial you write that you can use the command
       
           global/XXX/visual
       
         to search for the pattern "XXX" and edit/move around (remember,
         Hal needed this command to edit the linted spaghetti-code...)
       
         But there's one problem: suppose I found, after the 10th XXX of
         100, that I do not want to view the remaining 90 occurences.  It
         works as long as I don't type 'Q'. But now I want to view/edit
         the code where my lint report is something like "illegal", I have
         to type Q and then global/illegal/visual.
       
         And now there's the problem: typing Q doesn't prompt for a new
         input, it moves to the 11th occurence of "XXX".
       
         Do you know my problem?  Is there a way to stop vi moving on with
         the global command after typing Q?
       
         Thanks a lot in advance!
       
         Chris...
       
       As Chris clearly realizes, ordinarily there is no problem with
       omitting the remaining 90 stops.  Each time this command puts you
       into visual mode somewhere in the file, you are not restricted to
       fixing one limited problem.  You may move anywhere in the file,
       edit whatever you like, and keep doing this as long as you please.
       When you finally finish all the edits you've decided to do, you
       can write the file and quit the editor in your usual way--the
       suspended global command will silently disappear at this point.
       
       But going into a second string of visual mode stops from a new
       global command, as Chris wants to do, requires finesse.
       Obviously, it's not possible to use the Q command to return to the
       line-mode command prompt until every one of those 100 lines has
       been visited and the first global has terminated.
       
       The best way out of this predicament starts with writing your
       changes to the file.  Then, instead of typing Q type an :edit
       command.  This brings up a fresh copy of the file you are editing,
       but since you've just done a write, the fresh copy is identical to
       the one you've been working on. Because you haven't left the
       editor, most of the state is saved--contents of the named buffers,
       any maps and/or abbreviations, values of the set  command options.
       You do wipe out a few small items like the contents of the unnamed
       buffer--and, of course, that suspended global command.
       
       Now you can use the Q command to go into line mode, then run that
       second global command.
 (DIR) Solutions
       
       In The Next Installment
       
       In this tutorial to date, you've undoubtedly seen some aspects of
       the editor that you wish had been designed differently.  The good
       news is that many of these features are yours to change at
       will--without hacking up the source code and recompiling.
       
       In Part 5 of this tutorial, I'll elucidate the editor's built-in
       facilities for setting up your own editing environment, and the
       many factors you can modify this way.
 (DIR) Part 5: Take Control of Your Editing Environment
 (DIR) Back to the index