Wednesday, September 3, 2008

vi we forgot

It is really hard to get excited about learning things we figure we know enough of, but vi has a lot to offer so it may be worth a minute or so to look it over again. Most of us read a vi manual at some point, and were impressed with how much a few keystrokes can do, but as time wears new grooves in our brain, we forget the functions and the keystrokes. This only takes a few minutes to read, but that is because it only has part of what you want, but maybe it will remind you that it can save you work so why not look some more stuff up?

One important hint, don't use the mouse unless you are really hard to confuse.

Here are few that might have got away:

Regular expressions: Depends on what . means
. Matches any single character except a newline.
* Matches any number of the character that precedes it
^ Start of a line. ^... would match any 3 characters starting a line
$ End of a line
\ Escape special character \$ would just be a dollar sign, not EOL
[ ] Matches any single character with in the brackets. a-z a range, would match b,c,d etc.

Changing text
i Insert text
A Append to current line
I insert at start of current line
o open a line below
O open a line above
cw Change word
C Change to end of line
c2b Change two words back (to the left on the line)
c$ Same as C, change to end of line
c0 or cc Change to end of line, but start at beginning not in the middle.
dd Delete the line, put it in a buffer that p can put back below the then current line.
yy or Y Yank a copy current line to buffer, p can insert it as described above.
r Replace one character, exit from insert mode after changing text.
R replace them as you type (leaves you in insert mode).
xp Erase the character at the cursor and put it after the next character.

Moving around
k Go up one line, 4k go up four.
j Jump down one line, 8j jump down 8.
h Move one space towards the head of the line. numbers work here also
l Move one space towards the end of the line.
Ctrl F Go down one screen (forward)
Ctrl B Go back one screen
Ctrl R redraw the screen
0 or $ Go to start or or end of line
:1 :$ go to line 1 of the file, $ the last line
Ctrl G Where am I?
nG Move to line number n
( move to start of sentence
) move to end of sentence
e Move to end of word
z {Return] Move line with cursor in it to the top of the screen

Repeated edits
. Repeat the last edit.

If you are going to make the same edit in a lot of files call them all at one time, as in:
vi *.sql then use (say) a global replacement to make all your changes, or if the replacement
is not global, use search / and . to find the lines and repeat the edit, or n to find the next.
When you are done with a file, save it, and use :n to get to the next file; vi will remember
your last edit so you can avoid typing it in again. Or get sed to do this kind of thing, it
is less error prone.

Multi line edits
:%s/^M// ex command: % all lines substitute/(type ctrlV, ctrlM/ / (with null)

That will get rid of all the MS (misbegotten) ^M (EOL) that you see when Unix opens an MS file.

Writing to files, reading from files
Be careful about exiting after you write to a file, vi will let you exit without saving if you have just written anything, so if you are (say) in SQL*Plus, and are editing with vi, and write to a file to save your code before it can get lost, if you exit without saving again, you will return to the buffer you had when you left, and not the code you just edited. You can read your new file in, but thinking ahead may be even better.

ZZ -- vi command: save and exit; like ex command :x
:w -- write to whatever the OS thinks is the file
:w my_file -- write to my_file but does not make my_file the current file
:1, 10 w my_file -- write lines 1-10 to file
:.,+10 w my_file -- start here and write this and the next 9 lines to a new file
:.,+10 w >> my_file -- as above but append to file if existing.
:r /u01/oradata/my.sql -- read a new file into the current buffer at the cursor
:r ! sort my_data -- read the file my_data, and use the shell to sort it before inserting.
:e /u01/oradata/my.sql -- if saved, release the current buffer and edit a new file
:e! /u01/oradata/my.sql -- abandon the current buffer and edit another file.
:e! --- abandon my edits and reload this file from disk.
q! -- quit, don't save and don't open another file for me.

Finding deleted text from the last 9 deletions:
"1p restore the last deletion (has to be more than a few characters)
Okay, was that what you wanted? No? You can get any of the last
9 by that method or step throw them one at a time, undoing the wrong ones:
"1pu.u.u.u. or "[1-9]p if you know which buffer you need.

(Put 1 back, no, undo that, . (repeat). undo that also, . u . u, Okay that is it.)

Yanking to a named buffer
"a7yy (yank the next 7 lines into the buffer a)
"ap (put the buffer a after the cursor)
"aP ( put buffer a before the cursor)

Bookmarks (only last during a session, file )
mb Mark this line as b
'b Move to line marked as b

Seeing and setting options
: set (show options that are not the default)

:set ic make search be insensitive to case
:set noic set back to default
:set showmatch (useful tomatch ( and ) in code)
:set noshowmatch (turn it off)
:set number (show line numbers)



Filtering: Letting Unix shell tools help

You can either use vi or ex to filter using Unix tools

ex
:.,+10! sort

vi
11!!sort

.exrc The vi init file

You can have different .exrc files in different directories (at least in Solaris) if you have set exrc in the .exrc file in your home directory. That means that you can abbreviations that fit the code you are typing in the directories where you would be working.

Home Directory
set exrc

Sql Directory Note: use <<>> to adjust tab depth or Ctrl D or Ctrl T ( both in insert mode)
set tabstop=3
set shiftwidth=3
set autoindent
set number
set showmatch
ab wor WHEN OTHERS RAISE;
ab else ELSE
ab if IF

No comments: