Sometimes I'm on a system without Vim, and use the default nvi (BSD systems) or the original vi (Arch Linux).

There are quite a few differences, but the largest annoyance is that I can undo only my last operation. Pressing u the second time works are a "redo".

Is there some way to get this working?

up vote 14 down vote accepted

From nvi(1):

 u       Undo the last change made to the file.  If repeated, the u command
         alternates between these two states.  The . command, when used
         immediately after u, causes the change log to be rolled forward or
         backward, depending on the action of the u command.

So press u, and then keep pressing . for more undo; If you press u again, it will 'reverse' direction and pressing . will be a redo.

I never knew about this until yesterday; and thought it was somehow a new feature, but it seems like it has worked like this since at least nvi 1.79 from 1996.

This doesn't work in the original vi; where the undo is documented as:

   u      Undoes the last change made to the current buffer.  If repeated,
          will alternate  between  these  two  states,  thus  is  its  own
          inverse.  When  used after an insert which inserted text on more
          than one line, the lines are saved in the numeric named  buffers
          (3.5).

Which is really a complicated way of saying that pressing u again will redo your changes.

Which is also what Vim's :help undo says (and why I assumed it also wouldn't work in nvi):

 u                       Undo [count] changes.  {Vi: only one level}
  • Your "answer" appears to just restate the premise of the question. So the answer is "no"? – 200_success Feb 22 '15 at 19:51
  • 1
    @200_success It's "yes" for nvi (with the .), but indeed "no, this is not possible" for the original vi... So only that part confirms (or "restates", if you will) the premise of the question. – Martin Tournoij Feb 22 '15 at 20:46

The closest thing the original vi has to multiple undo (aside from U which can revert multiple changes within a single line) is the numbered registers, which hold the nine most recent changes or deletions.

If you put from a numbered register, subsequent dot commands will increment that register when it repeats the command.

E.g. with the following text, with the cursor line indicated with >,

  aaaa
> bbbb
  cccc
  dddd
  eeee

the command dd.. will result in:

  aaaa
> eeee

If you then type "1P, vi will put the most recent deletion from register "1:

  aaaa
> dddd
  eeee

Hitting . will put the contents of the next most recent register, by doing "2P, and hitting . again will put the contents of register "3.

So, in short, "P.. will put back all the text you deleted, leaving you with

  aaaa
> bbbb
  cccc
  dddd
  eeee

Not brilliant, but better than nothing! More usefully you can use it at the beginning or end of the buffer to quickly inspect what's in your numbered registers. Then you can easily delete what you don't need.

It's documented in vim under :help redo-register.

Using the original vi, hit [n]u to go back n steps. To progressively go back step by step...

  • hit [n]u to go back n steps
  • then hit [n]u to redo n steps
  • then hit [n+1]u to go back [n+1] steps
  • etc
  • 1
    I have something close to the original vi, and it doesn't seem to go back n steps. – muru Apr 18 '16 at 19:49
  • Agreed. Original Vi can revert only a single change with u, or restore a single line to how it was before you started editing it with U. – Antony Dec 26 '16 at 15:13

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.