Okay, I'm not done talking about Vi yet. Lots of you out there are Emacs fans, and that's fine. I used to be too. And there are still some things I haven't figured out how to do quite as easily with Vi, such as SGML editing, but that's okay. You can either suffer through another Vi article or wait until next time for something more to your liking!
Requirements. Before you can do interesting things with Vi, you need to know how to use some mechanisms that are beyond the basics:
Example Mode. Nothing teaches like experience. So let's put ourselves to the task of creating a ``mini mode'' for creating HTML documents using the above concepts.
First, we need some everyday insert mappings. These we can put
into our .exrc file in our home directory. (Note, when you
see a backslash (``\'') at the end of a line, it indicates
an artificial line break that would not exist in your macro, but
is set here for typographical reasons.)
ab Hndoc <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">^M \
<HTML>^M<HEAD>^M<TITLE> </TITLE>^M^M^M</HEAD>^M \
<BODY TEXT="#000000" BGCOLOR="#FFFFFF">^M^M<BR>^M^M \
</BODY></HTML>^M
This first abbreviation means that when you type ``Hndoc'' into a
document, those letters will immediately be expanded into the
basic tags for an HTML document. Some keystrokes, such as the
return key and the escape key, cannot be entered directly into an
abbreviation or macro. They must be ``escaped,'' meaning that
another character must precede them so Vi doesn't prematurely
interpret the character. When you see ^M, you are seeing
an escaped return carriage character, for example.
So, all of what you see above will actually be on the same line
when you type it into your ~/.exrc, and the returns are
entered by pressing Ctrl-v. You hold down the Control key
and tap the ``v'' key, then enter either the return key or the
escape key. Then the proper sequence will be inserted into your
saved keystroke sequence. In the future, I'll refer to these
strokes you type as ``CtrlVEsc'' and ``CtrlVRet'' instead of by
the symbols that appear on the display when you type them.
You saved yourself quite a few keystrokes with this single abbreviation already. But there's much more.
How about ab H-1 <H1></H1>CtrlVEsc4hi This will abbreviate the sequence ``H-1'' and create a level 1 head with it, leaving the cursor between the begin and end tags in insert mode. (CtrlVEsc4hi tells you to hold Ctrl-v and hit Esc, thus bouncing to edit mode, moving the cursor four places to the left, then turning insert mode back on.)
You can create a host of these type of commands. But what about something more interactive?
Try this:
ab Han <a href="CtrlVEsc:r!cat \/dev/ttyCtrlVRetkJx$a"></a>CtrlVEsc?</a>CtrlVReti
This will bind the ``Han'' sequence (``H'' for HTML mode, ``an'' for anchor) to an anchor element, but before it completes, it will ask you to enter the URI to reference. When you enter Crl-D to end your URI input, the rest of the macro will complete and finish your entry, leaving you in insert mode with your cursor positioned to enter the text between the start and end tags. The last part of the macro joins the two lines created, moves to the end of the line, then searches backward for the start of the endtag, then bounces back into insert mode for you.
Let's say you are editing your document and decide you want to highlight some text and insert an anchor element around it. You could go with the following map command:
map ^X^a `oi<A "href="#">CtrlVEsc`ca</A>?">CtrlVReti
This macro assumes you mark the first part of the anchored text with marker ``o'' (for open tag) and the last part of the anchored text with ``c'' (for close tag). It inserts open anchor tag before the text, bounces to edit mode, moves to the close tag marker, bounces back to insert mode, inserts the close tag, bounces to edit mode, searches backwards for the href value, then bounces back to insert mode so you can insert your text at the appropriate location.
Further, you could combine some macros by chaining them together.
Let's say you have a macro ^Xg for ``get text'' that said:
map ^Xg :r!cat /dev/ttyCtrlVRetkJx
which effectively asks you for input, then pastes that input into your document at the current cursor location. You can embed this macro into another macro, thus chaining them together:
map ^Xu 0i<a href="#EscVEsc^Xgi</a>EscVEsc
This macro inserts the opening anchor text, stops, starts the
^Xg macro to get the text for the URI reference, then
completes the insertion of the closing anchor tag.
You could also put each of these macros in a file other than .exrc, such as ~/vimstuff/html.exrc. Then, when you
wanted to use an HTML mode, you could simply type
:so ~/vimstuff/html.exrc while in Vi mode.
This should give you a few ideas on how to build an HTML ``mode'' for Vi. Mind you, you can easily start with modes developed by others and expand or replace from there. I use Vim (see http://www.vim.org), and it comes with a HTML syntax highlighting mode, but there is still a lot of room for customization of abbreviations, macros, mappings, and for sourcing external macro files and storing them into memory.