« God is watching... | Main | Elbows on the table... »

April 01, 2005

Vi (or ViM)

I promised that today would be about vi (or vim) even though a better tip came along yesterday...

Vi is the grandfather of Unix editors - it was originally written by Bill Joy at UCB (yes the same Bill Joy who worked for Sun). Given the origins and the long history of the editor, you can bet that there must some hidden secrets.

Firstly, I need to explain to newcomers why vi is like it is and then I will move onto to showing how a pipe works in vi.

People who meet vi for the first time usually recoil in horror - where are the menus and mouse actions? Well vi was written at a time when those accessories did not exist - in fact you could run vi on terminals that did not even have arrow keys. To cater for such a limited hardware environment, the original design was for a pure modal editor - vi is either accepting instructions from you or it is adding text to the file. That mens if you are not getting the desired effect, you are probably in the wrong mode :-)

Command mode (where you tell vi to do things) is the default mode, you switch to text entry mode by using one of the commands that (a)dds or (i)nserts text (there are others as well such as (o)pen and (c)hange but the most common commands are 'a' and 'i'). To get back to command mode, you need to press the ESC key.

OK, you need to create a file on your nearest Unix box. If you want to play along, pick a directory with some files in it (like /tmp or you home directory). Let's call out file 'foo' (a time-honoured name for a scratch file):

vi foo

We are in command mode so type 'a' to add some text to the file. You will not see this 'a' on the screen. Type a few blank lines and then a line that contains the words:

ls -als

followed by a few more blank lines. Now hit ESC to get back command mode.

You can move around the file using the arrow keys (or if you don't have them, use 'h', 'j', 'k' and 'l'). Move the cursor to somewhere on the line with text on it. Exactly where on the line does not matter. Now we are going to trade this line for the results of a Unix command. Carefully type the following (including the colon):

:.!sh

(That was a ':', '.', '!' and the letters 's' and 'h'). The colon tells vi that we want to talk to the line editor underneath vi (ex), this is important because the way ex counts lines is a little different. The full stop says to use this line only. The exclamation mark says to pipe the left hand side (the line in the file) to the right hand side (the default Unix shell). When this returns, the results will replace the input line. You should have a long listing of all the files in your current directory inside your foo file.

Note that the command can be considerably more complicated and you can even chain commands together over multiple lines. Note that to send multiple lines to a pipe, you need to select them using the ':' and '.' operators. For example to pick the two lines before this one and one afterwards, we can say:

:.-2,.+1!sh

Note the use of a ',' to separate the left hand and right hand end of the range. If you want to know more about vi (or vim), drop me a line...

Posted by Ozguru at April 1, 2005 06:00 AM