linuxnewbie.org.gif
Tuesday, 12-Dec-2000 10:32:56 EST
Newbized Help Files articles discussion board bookshelf sensei's log advertising info
Customizing vim
Written By: Danny "Strike" DiPaolo

Don't forget, the comments can be used in these files as well. The main macro I wanted to use as an example was the last one. Remember before with the LaTeX example when I said you could run all of those commands in one? Well, this is a really simple way of doing it. The ",a" macro in this set of macros (which resides in my ~/.vim-files/.vimrc.asm file that is referred to in my main ~/.vimrc above) simply runs the first three macros in order. Another way I could have done this would have been to actually take all three of the commands used in the other three macros and to concatenate them all together. But, it's much much shorter to just run the three things we have already defined. So, instead of having to type ,n,l,r we can save ourselves some keystrokes by just typing ,a instead. Kinda neat, huh?

Okay, that is about all of the really neat stuff to do with command mode macros that I have to show you guys, so the next (and final) step is ...

:::Input mode macros:::

These are very closely related to the command mode macros, but with their own tiny little subtleties. Let's take a look at some examples, this time some examples I use in my C macro file:

-----------------------

map!    ]if             if () {^[o}^[keei
map!    ]for    for () {^[o}^[keei
map!    ]while  while () {^[o}^[keei
map!    ]inc    #include <.h>^[hhi
-----------------------

Now these probably look incredibly cryptic. Part of them may look somewhat straightforward, but if you can get them from just looking at them, I'd be very impressed.

An important point to reiterate is that these macros are all entered while you are actually still in input mode. For example, if I were to type "]if" in input mode, it would perform the first macro (which I will get to the meaning of in a bit). In the same vein, typing something like "]ifa" would first expand the first macro and then put an "a" wherever the cursor ended up after the macro was complete. So, it is important to choose things that you are not likely to actually type in whatever you are typing, because otherwise they will expand to the macros you defined. This is why my macros begin with the "]" character. I don't use the "]" character for anything in C except for arrays, and it is rarely ever followed by words like "if", "for", etc. And even if it was, I do not think it is ever necessary to use it in that fashion - these letter combinations can pretty much always be avoided. However, I also like them to be fairly easy to remember as well, and I think these examples exemplify that as well.

As you may have noticed, we are no longer using "map" to define our macros, but "map!" instead. Well, this is what defines an input mode macro. "map" is only for command mode macros. I generally put these in a separate section from my command mode macros so as not to clutter up my .vimrc files too much so that I can further customize them later.

Okay, with all of that covered, let's tackle what these macros expand to. Much like the command mode macros, you basically think of what keys you want to be pressed, remembering that you start in input mode. Well, I'll go ahead and tell you ahead of time what each of these macros is for in case you haven't already figured it out. The first three are basic macros to create a syntactically correct if/for/while loop quickly. The last one is simply a shortcut for including files, and you will see how it works.

's take a look at the first one. Let's assume we are editing the source code for something and we have these definitions sourced. I'm in input mode and I'm ready to begin an if statement. Normally, I'd just start typing something that might look like this:

-----------------------

        if (a <=
-----------------------

But the problem here is this, I've already decided that I want to use an if statement, but I can't focus entirely on the process that needs to take place within that if statement because I have to remember to close the loop in order to follow syntax correctly. In fact, with normal typing methods, closing the if statement is the last thing you do even though it is the first thing you decide with regards to that program block. True, you could simply type out a basic if statement first so that it was syntactically correct and then fill in the appropriate statements, but that doesn't really apply here now does it?

Actually, yes it does, very much so. In fact, that is exactly what we are going to do. But we will take it one step further. We will reduce that step to a much smaller number of keystrokes (as you will see). Now, a syntactically correct if statement looks like this:

-----------------------

        if () {
                            
        }
----------------------

where the <condition> and <program statements> vary from task to task. So, we want to insert this little bit:

----------------

        if () {
        }
----------------

and then prepare ourselves to start thinking of the condition we want to put in this particular if statement. So, we've got our problem nailed down now. Next we'll see how my macro does exactly what we want.

It's pretty obvious (now that you know what input mode macros do) that most of this is fairly trivial. In fact, the entire first line is very simple, it's just the part that reads "if () {" - since we are in input mode, hitting those keys simply puts them in the file like we want. However, now we have a bit of a problem. We have to move the cursor down a line and input a final "}" and THEN we have to move the cursor back on top of the second parentheses and drop ourselves back into input mode (for the most seamless behavior - we start in input mode, we should end in input mode, we did the same for command mode macros too). Well, there are two ways to advance to the next line, actually.

One is fairly easy, and the other a little tougher but more illustrative. The "fairly easy" method would be to simply to hit Enter and then insert the final brace. However, I prefer the latter method because it is more illustrative. This method is to escape OUT of input mode (yes, into command mode), to begin a new line in input mode with the vi command "o", and to insert the final brace. But, how does one enter in <Esc> as a character into a macro? The only way to do it is to hit CTRL-V while in input mode and then hit the <Esc> key. It produces two characters like this ^[ but it isn't the same if you just type those two characters in (if you do, then you will have a "}^[" at the end of your if statement at this point in time.

Okay, now that we have gotten all the characters in place we have two objectives left to accomplish - positioning the cursor so that we are in between the parentheses (realistically, on top of the second paren), and to make sure we end up in input mode for our seamless transition.

First, let's remember what we've done and where we are. This is what our setup looks like right now:

-------------------

        if () {
        }_

        ---INSERT---
-------------------
(the underscore represents the current cursor position)

Well, now we are going to position the cursor, but there is not any way of moving up a line in input mode, so we have to escape out again. That is what the next ^[ in the sequence is for. This will put the cursor back one spot, directly on top of the curly brace (on the second line). We then want to move the cursor up one line using the vi navigation keys HJKL - the appropriate one for this one is of course, "k". Now our cursor is on top of the "i" in "if" - we have to move it forward to the end of the "word" after it (well, this "word" is just the set of two parentheses, but it will do). So, we put it at the end of "if" by telling it to go to the end of that word (e) and then we tell it to go to the end of the next "word" (e). Now we are in the right position, but have one thing left to do - return to input mode. And any seasoned vi user can tell you that "i" will put you back into input mode from command mode.

You string those all together, you get:

--------------------

for () {^[o}^]keei
--------------------

You may have noticed that using "e" to go to the end of "if" in the last example was unnecessary and could have been done by moving right one instead with "l". Well, that is true for "if" because it is a two-letter word. Examine the macros I use for for and while and notice how they can be almost identical because of the usage of "e" instead of simple direction keys. In fact, now is a good time to take a good look over those and notice the similarities.

Once you are satisfied with what you see (and maybe even comfortable, but that may be aiming too high), we'll proceed to the final exercise which is simply analyzing that last macro (a trivial process now that we just did a more difficult one.

The last macro reads:

--------------------

map!    ]inc    #include <.h>^[hhi
--------------------

Any C programmer would notice right away that that looks a lot like an #include line for inclusion of a header file, but it's missing a name. Well, the rationale behind this one is similar to the one I used in justifying the whole skeleton file idea. Basically, every #include'd file follows the same format, only varying in one tiny bit (the part of the filename before the .h). So, instead of typing stuff like this:

-------------------

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
------------------
(this is an actual set of #includes from a small sockets program)

I just wrote a macro that will print out

------------------

#include <.h>
------------------

and then put me in input mode before the ".h", with a construct like that in place, writing all the includes is a trivial process that becomes much faster.

Let's analyze what we need to do. First, we need to output what is shown above, and then we need to simply position the cursor on the period and go back into input mode. Like I said, after what we just did, this is pretty trivial.

The first part is easy, it's just the text ("#include <.h>"). Next we escape out of insert mode so we can move the cursor ("^[", our cursor is now on the ">"). Then, we move it on top of the "." by moving it left twice ("hh"). And, finally, we put ourselves back into input mode ("i"). And <begin cheerleader voice> What's that spell? </cheerleader>

"#include <.h>^[hhi" !!!

Excellent! You now have a few more tools in your vim toolbox to get you started on customizing vim to your needs. For more info, read the online help or just experiment. There is a ton of other stuff you can do, but this is enough to keep you (and me) busy enough for a while. Enjoy!

1 2 3



Would you like to have your article published online? Send them in to newfiles@linuxnewbie.org
[-NHF Control Panel-]
The Linux Channel at internet.com
Linux Planet
Linux Today
Linux Central
Linuxnewbie.org
PHPBuilder
Just Linux
Linux Programming
Linux Start
BSD Today
Apache Today
Enterprise Linux Today
BSD Central
All Linux Devices
SITE DESCRIPTIONS
[-What's New-]
Order a Linuxnewbie T-Shirt
Easy Webcam NHF
Directory Navigation NHF
Installing Snort 1.6.3 on SuSE 6.x-7.x
Customizing vim
The SysVinit NHF
Installing ALSA for the VT82C686 integrated sound
USB Creative Video Blaster II for Linux
Configuring the Intellimouse Explorer in XFree86 V4+
The beginnings of a distro NHF
Getting Past Carnivore?
Getting and Installing PGP
Getting your ATI Rage 128 Working
How to create a multiple partition system
Using Fdisk
Introduction to Programming in C/C++ with Vim
Adding a Hard drive in Linux -- In five steps
Installing ALSA for the Yamaha DS-XG Sound Card
Getting your Diamond Rio Mp3 Player to work with Linux
Bash Programming Cheat Sheet
Installing NVIDIA Drivers for Mandrake
Setting up Portsentry
Hard Drive Speed Tweak for Linux
Sensei's Log
Chat room
Join: Linuxnewbie.org SETI Black Belts!
Send in your news
Click the image to add Linuxnewbie.org to your MyNetscape Page
[-LNO Newsletter-]

[-Archive-]
The beginnings of a distro NHF
Connecting to the Internet using KPPP
Getting your SBLive to work
Unreal Tournament NHF
LWE Day 2 Pictures
LWE Day 1 Pictures
The LNO FAQ!
WoW (Words of Wisdom)
Other sites news
What is Linux?
What is Linux? part deux (ups & downs)
Search newsgroups
The List
ALS Report
Feedback Form
jobs.linuxtoday.com.gif
Match: Format: Sort by:
Search:
[-Quick Links-]

Copyright 2000 internet.com Corp. All Rights Reserved. Legal Notices Privacy Policy

internet.com.gif