Monday, February 2, 2009

Fun with vi, nvi, and vim

Some time ago, I installed the old version of vi ported as part of the heirloom project, noted as Traditional Vi. I tucked it into ~/code/C/src/old-vi and put a symlink named 'ovi' in my $PATH. During initial testing, I quickly concluded that the nvi builds on modern BSD (the systems vi) are considerably more extended then what the traditional vi offers. Things that I noticed most missing, were that '~/' in file names was not expanded to the value of ${HOME}/ like in the shell (nvi / vim expand ~/), and the (crappy) split window support and a proper implementation of . and ^R (nvi makes ^R behave like .). A little playful testing also showed several settings missing (mostly expected), and no :exusage or :viusage commands. (Useful in nvi/nex on occasion, to see just what is available without consulting a reference or vim :help.) Two things I've learned tonight, old vi and nvi both support abbreviations, and control+^ is down right handy for switching buffers (vi, nvi, vim; probably every vi clone ever made). I thought abbrivations would have been an Elvis invention that made its way into vim, but I guess it was there since the 1980s, hehe. I also noted that ovi/nvi react differently to showmode (I prefer ovi's).



Out of curosity, I fed into vi my nvi configuration file, since it appeared to be ignoring my ~/.exrc. Only had to remove the matchtime / ruler settings, and two of my mappings: gg and ZQ. gg being a vim'isms for 1G (go to first line in file) and ZQ being a very logical vim'ism for :q!^M much like vi used ZZ for :x .After that, vi accepted it without problem. The errors about the mappings interestingly said, "To dangerous to map that", but nvi doesn't give a darn. Fair enough for gg, but I've yet to figure the ZQ one yet.



Traditonal Vi
~
~
~
~
~
~
~
:set all
noautoindent            nomodelines                     noshowmode
autoprint               nonumber                        noslowopen
noautowrite             open                            nosourceany
nobeautify              nooptimize                      tabstop=8  
directory=/var/tmp      paragraphs=IPLPPPQPP LIpplpipbp taglength=0
noedcompatible          prompt                          tags=tags /usr/lib/tags
noerrorbells            noreadonly                      term=screen            
noexrc                  redraw                          noterse    
flash                   remap                           timeout
hardtabs=8              report=5                        ttytype=screen
noignorecase            scroll=11                       warn          
nolisp                  sections=NHSHH HUnhsh           window=23
nolist                  shell=/usr/local/bin/zsh        wrapscan 
magic                   shiftwidth=8                    wrapmargin=0
mesg                    noshowmatch                     nowriteany  
[Hit return to continue]                                          

FreeBSDs build of nvi, when invoked as vi or nvi:
+=+=+=+=+=+=+=+                       
noaltwerase     noextended      matchtime=3     report=5        term="screen"
noautoindent    filec=""        mesg            ruler           noterse
autoprint       flash           nomodeline      scroll=11       notildeop
noautowrite     nogtagsmode     noprint=""      nosearchincr    timeout
backup=""       hardtabs=0      nonumber        nosecure        nottywerase
nobeautify      noiclower       nooctal         shiftwidth=8    noverbose
cdpath=":"      ignorecase      open            showmatch       warn
cedit=""        keytime=6       optimize        showmode        window=23
columns=80      noleftright     path=""         sidescroll=16   nowindowname
nocomment       lines=24        print=""        noslowopen      wraplen=0
noedcompatible  nolisp          prompt          nosourceany     wrapmargin=0
escapetime=6    nolist          noreadonly      tabstop=8       wrapscan
noerrorbells    lock            noredraw        taglength=0     nowriteany
noexrc          magic           remap           tags="tags"
directory="/tmp/"
msgcat="/usr/share/vi/catalog/"
paragraphs="IPLPPPQPP LIpplpipbp"
recdir="/var/tmp/vi.recover"
sections="NHSHH HUnhsh"
shell="/usr/local/bin/zsh"
shellmeta="~{[*?$`'"\"
Press any key to continue [: to enter more ex commands]: 

And doing :set all in Vi Improved (VIM) is so huge, it requires a pager! Hahaha.



Generally I will use vim whenever it is made available, in fact I usually compile my own binaries for it via shell script. But I have spent enough time using nvi, that dipping into ed, ex, vi / nvi don't bother me. When I invoke vi, I expect a fairly traditional vi; when I invoke vim, I expect vim with vi compatiblity mode turned off (e.g. as if invoked as vim -U NONE -u NONE -N), or vim to behave 'as expected' when my own vimrc file is around.



My ~/.vimrc is over 1000 lines, but if you strip blanks and comments it is closer to 600. The only customizations that I actually depend on however, is mapping ';' to ':'. Although certain vi users find that to be ludicrous, I use :ex commands much more frequently then I need to repeat the f, F, t, and T commands in the same direction. So being able to say ; when : is needed, is a massive life safer on my fingers, because it removes the need to hold shift. In fact, unless I want to go to a specific letter in a word, I usually employ :/ and :? to search for the word, rather then a linewise [count]f[character] motion, so the loss of a standard ';' is fairly low for me.


I find vim much more comfortable then other vi's, because I spend an imense amount of time in a text editor. I often [ab]use vims :sp[lit] command to have multiple edit-windows open, or to edit the 2 different parts of the same file without using marks or tags to jump about. The gq operator in vim is also a thing I love, because I can quickly reformat text without having to invoke an external program like fmt(1) all the time. Vi Improved also has better tag based commands. The ability to auto complete :ex commands and file/directory names helps me greatly; nvi's cedit extension for editing :ex comand history sucks in comparason. The ability to :e . and use vim to peruse the current files in a directory is also nice when dealing with some peoples projects, although :!ls | less would work too, I'm not fond of the hit enter prompt at the end (nvi also ditches the colours in my ls output, while ovi retains them). The ability to use code folding and quickly configure settings based on file type is also quite nifty, since I often use zM to fold everything in large files, take a look and zO things that /look/ like it is what I am looking for. I almost never use ^O to make a single normal mode command from insert mode (vi/nvi don't seem to support it), but it is nice when combined with other control+ commands in vims insert mode.


I'm also partial to vim's undo style that repeatidly pressing 'u' in normal mode, repeatidly undo's things while ^R redos what was undone. Traditional vi, nvi, and vim with u in the vi compatiblity options all have semi-incompatible usage paterns. The Vi Improved way uses u as noted above, when set to use a more Vi compatible way, vim uses u to undo and ^R to redo. Because vim has unlimited undo/redos, this means we would press u to undo the last change, then ^R to 'redo' the previous commands, and a following u will undo will undo the last redo (undo redo redo undo; rather then undo undo undo redo). Nvi allows using the '.' as a synonym for ^R which is convenient since '.' means repeat last change command. While traditional vi seems to lack multiple levels of undo/redo period and end of quote.


vim style multi undo:

dddddd      -- delete the next 3 lines as 3 separate changes (3dj would be a single change)
uuu         -- undo last 3 changes (i.e. undeletes those 3 lines)
^R^R^R      -- redo last 3 undos (i.e. re-delete those 3 lines)

nvi style multi undo:

dddddd      -- delete the next 3 lines as 3 separate changes (3dj would be a single change)
u           -- undo last change (undelete last line)
^R^R        -- redo last 2 undos (i.e. undelete the previous 2 lines)

vi style undo:
dddddd      -- delete the next 3 lines as 3 separate changes (3dj would be a single change)
u           -- undo last change (undelete last line)
u           -- redo last undo (redelete last line)
(i.e. vi style undo just toggles between undoing the last change and undoing the last undo, and ^R is subverted to allow multiple undos/redos in vim/nvi)


I've been using the vim style multi-undo for years, but have been wanting to adjust myself to the nvi style for ages. The only problem is, if I have to undo then do redo's, I prefer using '.' instead of ^R, haha! It seems to me, that technically nether vim using ^R for redo, nor nvi extending . for redo is purely vi compatible; but I personally feel extending . for the purpose, rather then clobbering ^R is a more logical solution. Although I can't really think of a reason to use classic vi's ^R instead of ^L on a modern terminal (read CRT or emualtor based terminal). The nvi style of multi-undo/redo also makes more sense to me, although most software users have been heavily conditioned by most programs to expect ^Z to undo the previous change up until the programs built in limit on undos.



Vim provides extensive mapping, syntax highlighting, build system integrations, and buffer options compared to traditional vi's, but I don't actually depend on it. Although most programmers I know, will cut your head clean off if you don't give them syntax highlighting (lol), I don't use Syntax highlighting.... I used to like using the astronaut and elflord colour schemes in vim; because I found them good for visually dumping syntax into my head. I.e. you can quickly tell what is what kind of syntactical element. But ever since I had to spend hours hashing out new PHP and SQL in a colourless remote terminal, I started to find the syntax highlighting to be distracting :\. The only times I actually use colours in vim anymore, are for directory listings, with other peoples HTML, and in my .vimrc file; when coding, I use no syntax highlighting what so ever.



If you can look at the horse-shit filled tangles of (broken) HTML, (idiotic) SQL, (kindergartener like) PHP, and occasional JS that are so horribly intermixed and mutilated, that some past [SAS] webmasters dared to call it code, and come to reading it without syntax highlighting.... you can live without syntax highlighting anywhere!!!

1 comment:

  1. Originally posted on my Live Journal:

    subject: nice read
    by: (Anonymous) on 2009-02-22 02:43 pm (UTC)
    comment: I came across this looking for a good reference on nvi configuration. You have a lot of the same preferences I do. :) Personally, I can't stand vim because of years of using the nvi style undo with . that trying to use ^R just drives me nuts.

    Anyway, we're in the minority, but there are those of us out there that like nvi and dislike syntax highlighting.

    Also, if you ever want another annoying point about vim to point out to someone, ask them why you use ":syntax on/off" instead of ":set syntax" and ":set nosyntax". I can make vim behave somewhat OK at work when I'm forced to turn off all the crap the programmers turn on with a simple ":set ts=8 cp nonumber" but then I also have to ":syntax off" on a separate line, rather than just including it in the same set command.


    subject: Re: nice read
    by: sas_spidey01 on 2009-02-22 06:56 pm (UTC)
    comment: The best reference on nvi configuration that I have found, has to be a toss up between using vims :help to check it, and using the traditional (old) vi and ex manual page to get more details on it. The manual page for nvi/nex contains the options you won't find anywhere else (like 'comment'), but is probably less helpful then SUSv3 on details. It's just to darn short! The old vi & ex manual pages however, is an excellent command and settings reference. The only thing to it is, unlike nex/nvi it is really two separate manual pages like the old days: link


    Vims compatibility options (:he 'cpo') allow tuning how compatible vim tries to be with traditional vi, without cutting off useful stuffs like tab-completion on the :ex command line, and related line editing features. Sadly, there is no cpo for making '.' behave as ^R, if the last 'change' command was an undo (like nvi). The . command is said to repeat the last change which ever doc you read on vi editors, but how the heck vim doesn't consider undo to be a 'change' to be repeated with . is beyond me!


    If your stuck with vim and have to do those setting changes without being able to adjust any ~/.vimrc file, you can actually put it on one line. The '|' pipe symbol can split ex commands kind of like ';' does in the Bourne Shell. So you would do

    :set ts-8 cp nonu | :syntax off

    The : before the syntax seems to be required in vim7, dunno why because it is almost never required after the pipe symbol with ex commands. (nvi/nex supports :| in roughly the same was as vim does, but I didn't think to test it in old vi/ex)

    ReplyDelete