Stephen Riehm's bracketing system

Last Updated: Thu 20 Jan, 2000
© Copyleft: Stephen Riehm, 1991 - 2000

Proposition:

Whenever you type a bracket or quote, you normally want the matching bracket or quote as well, and if you forget it, then you're going to have problems later.

Proposed Solution:

Whenever you type a bracket or quote, have your editor type the matching one for you.

Note: mapping these macros directly to the characters themselves is a bad ideatm - use macro names which aren't going to be confused with normal text. (Think about what happens when you cut'n'paste, or when you actually want to type a single bracket. i.e.: if( x == "(" ) )


The system:

The system essentially has two parts:

Bracket Insertion Macros
Macros for inserting matching pairs of brackets. These macros also take care of any formatting, indenting etc, and set a jump point just after the inserted text.

The Jump Point
A simple text marker left just after each inserted pair of brackets etc. to help automate cursor positioning after you have filled the text between the brackets. One macro simply positions the cursor at the next jump point. Sounds trivial, and it is, but it saves a lot of key strokes.

Both parts are needed for this system to work.

The macros:

Note: All macros presented here have been developed for vim, however, there is no reason why they shouldn't be applicable to any other editor you happen to like. The creation of suitable macros for your favourite editortm is left as an excercise for the reader.

I have found the Meta/Alt Key to be very useful, as vi doesn't use them by default. The macro files included also include a version of the macros which use double entry to trigger the macros for people stuck on systems which don't support Meta keys properly.

So here's an overview of the macros provided:

Macro with Meta keys Macro without Meta keys Description Example
DEL DEL Jump to next jump point marker (the marker is replaced by the cursor)
M-' '' Single quotes 'text'
M-" "" Double quotes "text"
M-` `` Back-quotes `text`
M-( (( Braces, no padding (text)
M-) )) Braces, with padding ( text )
M-[ [[ Brackets, no padding [text]
M-] ]] Brackets, with padding [ text ]
M-{ {{ Curlies, no padding {text}
M-} }} A new block, formatted correctly
    {
    text
    }
M-< << Angle brackets, no padding <text>
M-> >> Angle brackets, with padding < text >
M-; not provided shortcut M-) with trailing ; ( text );
M-\ )} short cut for M-)M-}
( text1 )
    {
    text2
    }
M-h not provided use the last typed word as a HTML tag, in this example, blockquoteM-h was typed. <BLOCKQUOTE>text</BLOCKQUOTE>
M-r not provided Enter a URL tag <A HREF="URL">text</A>
M-n not provided Set a HTML named index, for use with <A HREF="#name"></A> <A NAME="NAME">text</A>
M-fM-b not provided NROFF macro for Bold text \fBtext\fP
M-fM-i not provided NROFF macro for Italic text \fItext\fP

So what have you gained?

The real advantage comes when you are writing code, with lots of nested brackets. To give you a better idea, here's a quick demonstration. Here's a step-by-step example of how to use the macros to enter a typical if statement in a perl script: (the cursor position is shown with an _ (underscore))

You type: You get:
if <M-\> if ( _ )
    {
    «»
    }«»
-f <M-"> if ( -f "_"«» )
    {
    «»
    }«»
$<M-{> if ( -f "${_}«»"«» )
    {
    «»
    }«»
file<Del><Del> if ( -f "${file}"_ )
    {
    «»
    }«»
 && <M-)> if ( -f "${file}" && ( _ )«» )
    {
    «»
    }«»
$input = <M-<> if ( -f "${file}" && ( $input = <_>«» )«» )
    {
    «»
    }«»
STDIN<Del><Del><Del> if ( -f "${file}" && ( $input = <STDIN> ) )
    {
    _
    }«»
print<M-;><M-"><M-[> if ( -f "${file}" && ( $input = <STDIN> ) )
    {
    print( "[_]«»"«» );«»
    }«»
TRACE<Del> if ( -f "${file}" && ( $input = <STDIN> ) )
    {
    print( "[TRACE]_"«» );«»
    }«»
 Updating $<M-{>file<Del>\n<Del><Del> if ( -f "${file}" && ( $input = <STDIN> ) )
    {
    print( "[TRACE] Updating ${file}\n" );_
    }«»
<Enter>
update<M-;>$file, $input<Del><Del>
if ( -f "${file}" && ( $input = <STDIN> ) )
    {
    print( "[TRACE] Updating ${file}\n" );
    update( $file, $input );
    }_

So what has been simplified? First, there was never a need to check the bracketing! Secondly, there was no need to do any formatting - the cursor keys were never used! Keystrokes were also saved. (126 reduced to 95 - not counting shift and meta keys).

But there's more! What if you only want the trace output if a trace variable is set? Try this! (only the bold characters are a part of the macro set - the rest are normal vim commands)

You type: You get:
/trace<Enter> if ( -f "${file}" && ( $input = <STDIN> ) )
    {
    print( "[_TRACE] Updating ${file}\n" );
    update( $file, $input );
    }
V<M-\> if ( -f "${file}" && ( $input = <STDIN> ) )
    {
    _( «» )
        {
        print( "[TRACE] Updating ${file}\n" );
        }
    update( $file, $input );
    }
if<Del>$trace<Esc> if ( -f "${file}" && ( $input = <STDIN> ) )
    {
    if( $trace_ )
    print( "[TRACE] Updating ${file}\n" );
    update( $file, $input );
    }

I could make it more complicated if you like :-)

"Are they Modeless?", Did I hear you ask?

Well, almost :-)

Most of these macros are defined for insert mode and visual mode. For example: you can insert a new set of quotes when in insert mode by using the <M-"> macro, or you can quote after the fact by selecting the words you want quoted in visual mode, and then hitting <M-">. (it even works over multiple lines!)

The <Del> macro can be used in command mode or in insert mode, either way, you jump to the next marker and are left in insert mode. You can bounce on the <Del> key to clean up any left over markers - when it beeps (leaving you in command mode!) there are no more markers in the file (do you have wrapscan turned on too? If not - you might need to go to the top of the file and try again to be certain)

A quick HTML example

In HTML things are a little different. For convenience, the <M-h> macro uses the current word as the html tag. Thus, to type a new heading, you might try: h1<M-h>heading<Del>.

But there are problems!

Sadly! After the fact htmlifying can't (at the moment) prompt you for a html tag to put at the start and end of the highlighted text, so you have to do it yourself. Yet another what you type isn't what you get example, lets have some fun with a disfunctional line:

now highlight fun with vim's visual mode commands, and then hit <M-h>, you get: (cursor position is shown by the _ (underscore))

now all you have to do is fill in the tag at the start and the end, the following keystrokes will now turn the fun on strong:

or, as html would show it:

Making your own Forms

To create your own forms, use the macro <M-DEL> to insert a new jump marker. You can type text between the markers, and this text will be printed on the command line when the user jumps to that marker. ie:


     Name:       «user's name»
     Address:    «user's address»
     Account:    «user's bank account number :-)»

For further examples of forms, see the ../templates/ directory.

Tip: If you already have a common set of templates, try highlighting the parts you would normally replace and then using <M-Del> - the text you highlighted automatically appears between the markers.

The next step - installation

Installation of the macros is quite simple - really :-) Just follow these easy steps:

  1. Descide which macros you want:
  2. copy the above mentioned file to your home directory, and call it: .bracketing.vim. You'll also need to copy bracketing.base.vim to your home directory. (call it .bracketing.base.vim perhaps)
  3. Edit your copy of bracketing.vim. You should check the following:

  4. You may like to check the settings at the top of bracketing.base.vim (autoindent, cindent, etc.)
  5. Edit your .vimrc (Windows: _vimrc, Mac: vimrc) file to include the bracketing macros. You'll need something like:
  6. Start a new vim process and try them out!

Signoff

Well, you should now have an insight as to how these macros work together - they are orthogonal, easy to remember, easy to type (if you have Meta keys) and quite flexible. They are also free, and more or less unsupported. (if you send me an e-mail I'll probably answer)

Bug fixes, suggestions, comments and improvements are all welcome!

Enjoy!


Stephen Riehm
e-mail: Stephen.Riehm@bigfoot.com

© Copyright: Stephen Riehm 1991 - 2000