sponsor Vim development Vim logo Vim Book Ad

basic Tip #153: Making Parenthesis And Brackets Handling Easier

 tip karma   Rating 274/98, Viewed by 9454 

Read and edit this tip on the Vim tip wiki. The wiki may have a more recent version of this tip.

created:   November 4, 2001 11:56      complexity:   basic
author:   Joachhim Hofmann (Schuttberg)      as of Vim:   5.7

1) ++++++++++++++++++++++++++ "Automatic" bracket setting +++++++++++++++++++++++++++++
2) +++++++++++++ Further improvement of parenthesis/bracket expanding +++++++++++++++++
3) ++++++++++++++++++++++++++++ "Late" bracketing of text +++++++++++++++++++++++++++++
4) +++++++++++++++++++++++++++++ Conclusion ++++++++++++++++++++++++++++++++++++++ ++++

=======================================================================================

1) ++++++++++++++++++++++++++ "Automatic" bracket setting +++++++++++++++++++++++++++++

To automatically insert a closing parenthesis when typing an opening
parenthesis you can insert the following simple mapping to your vimrc:

:inoremap ( ()<ESC>i

This ends up with the cursor between the opening and the closing parenthesis
in insert mode.

You can apply this and the following tips, of course, with the kind of parenthesis/bracket
character you want to, i.e. (, {, [, < ..... and, pretty useful as well,
quotation marks ",',.... (to be continued)

2) +++++++++++++++ Further improvement of parenthesis/bracket expanding ++++++++++++++++++

I you are ready with filling the parenthesis/brackets, you likely want to
"escape" from the brackets again to continue coding.
To make this pretty comfortable, I invented the following kind of mappings, which get out
of the last expanded parenthesis/bracket, regardless of the actual type of it, and
enter append mode again.
I mapped this kind of "getaway" with CTRL_j, you may use your favorite keystroke with it.

...
:inoremap ( ()<ESC>:let leavechar=")"<CR>i
:inoremap [ []<ESC>:let leavechar="]"<CR>i
...
:imap <C-j> <ESC>:exec "normal f" . leavechar<CR>a

Explanation: The variable "leavechar" contents the actual char which is to "escape" from.


3) ++++++++++++++++++++++++++++ "Late" bracketing of text +++++++++++++++++++++++++++++

Occasionally I later want already written text parts to put in parenthesis.

I use the following macro, which brackets previously visually selected text.
I mapped it with _(.

:vnoremap _( <ESC>`>a)<ESC>`<i(<ESC>

Furthermore, a sort of mapping for bracketing a *single word* is conceivable.
Because this is not as general like the kind of visual mode mapping, I use
this kind of "word bracketing" only for surrounding the word right behind the cursor in insert mode with **.  I use the following macro to "emphasize" the word i just typed,
for newsgroup articles.

:imap _* <Esc>bi*<Esc>ea*<Space>


4) ++++++++++++++++++++++++++++++ Conclusion ++++++++++++++++++++++++++++++++++++++++++

Since I use these macros, I never caused a syntax error because of missing
brackets, and furthermore I can quickly insert parenthesis and qutotes into code-
and non-code files.

JH 04.11.2001

 rate this tip  Life Changing Helpful Unfulfilling 

<< Spelling checkers for: Dutch, English, German, Hungarian, and Yiddish | Mappings to facilitate the creation of text >>

Additional Notes

[email protected], July 31, 2002 12:12
Great tip!  Led me to create this mapping:

    inoremap { {<CR><BS>}<ESC>ko

to be used in conjunction with my autoindent setup:

    set expandtab
    set shiftwidth=4
    set smarttab
    set autoindent
    set smartindent

Now, any time i type a '{', this is what i get:

    {
        <cursor here ready for coding>
    }

Great time saver and it ensures that i don't ever miss a brace.  And it even works
for you crazy people who put the open brace on the same line as the for/while/function name ;)
atkinssc AT engr orst edu, August 6, 2002 7:31
Well in the last note, someone suggested a mapping that created:
{
        | <= Cursor
}

Although this is fine and dandy, f will not search anything but the current line; so I remapped it to use:
imap <c-j> <esc>:exec "/" . leavechar . "/"<cr>A

Now what would be great is if, when you hit ) or ] or } when you've already filled in the end charcter, to seek to the end and place your cursor outside of the block.

Any ideas?
[email protected], October 1, 2002 17:17
I think I'm missing something.  When I try to use the first tip, :inoremap ( ()<ESC>i, I get the text "()<ESC>i" when I type "(".
[email protected], November 9, 2002 11:53
You probably run vim in 'compatible' mode. (not recommended).
This happens usually when you have no _vimrc created.
Try renaming the file vimrc_example to .vimrc (UNIX) or _vimrc (Windows/DOS),
or set the option nocompatible: ":set nocompatible".

Achim
rwchin @ @ foxtrot . homeip . net, February 24, 2003 16:55
I modified this tip a bit to support different types of parenthisis better.  This one will remember the list of parenthesis you typed.

inoremap ( ()<esc>:call BC_AddChar(")")<cr>i
inoremap { {<cr>}<esc>:call BC_AddChar("}")<cr><esc>kA<cr>
inoremap [ []<esc>:call BC_AddChar("]")<cr>i
inoremap " ""<esc>:call BC_AddChar("\"")<cr>i
" jump out of parenthesis
inoremap <C-j> <esc>:call search(BC_GetChar(), "W")<cr>a

function! BC_AddChar(schar)
  if exists("b:robstack")
    let b:robstack = b:robstack . a:schar
  else
    let b:robstack = a:schar
  endif
endfunction

function! BC_GetChar()
  let l:char = b:robstack[strlen(b:robstack)-1]
  let b:robstack = strpart(b:robstack, 0, strlen(b:robstack)-1)
  return l:char
endfunction
[email protected], June 20, 2003 20:41
Very impressive!  As I was reading through the tip and trying the various incantations, the thought in the back of my mind was that this should use a stack.  And the final tip did it for me!  Thanks for the help, guys!
[email protected], July 3, 2003 9:39
I really like the last implementationl, but I noticed a slight problem.  The spacing inside the curly braces is not a single tab, it also includes spaces.  How do we get a single tab inside the curly braces.
[email protected], July 3, 2003 9:39
Sorry, wrong email address
[email protected], July 7, 2003 7:32
I ran into this too. If there's actually a space in the mapping in your .vimrc file it will get added to the mapping. So just make sure to remove the space.
If you check the current mapping by doing a
:inoremap {
if you did have that trailing whitespace it would show the mapping as
{ {<cr>}<esc>:call BC_AddChar("}")<cr><esc>kA<cr><Space>
Vim shouldn't interpret the whitespace as part of the mapping, perhaps this is a bug ?
[email protected], July 17, 2003 0:14
And what about abbreviations?
for example:
iab psvm public static void main(String[] args) {<CR><CR>}

with all of those mappings it produce :
    public static void main(String[] args){
    
    } }])


How to avoid this?
Anonymous, July 21, 2003 17:17
Use inorea instead of iab

This won't trigger the autobracketing.
Anonymous, July 24, 2003 22:22
Thanks!
[email protected], July 31, 2003 16:07
The following may be a little more complex than it needs to be, but allows me to type the closing character to get out of the delimiter, if I'm already at the end.

inoremap ( ()<ESC>i
inoremap [ []<ESC>i
inoremap { {<CR>}<ESC>O
autocmd Syntax html,vim inoremap < <lt>><ESC>i| inoremap > <c-r>=ClosePair('>')<CR>
inoremap ) <c-r>=ClosePair(')')<CR>
inoremap ] <c-r>=ClosePair(']')<CR>
inoremap } <c-r>=CloseBracket()<CR>
inoremap " <c-r>=QuoteDelim('"')<CR>
inoremap ' <c-r>=QuoteDelim("'")<CR>

function ClosePair(char)
  if getline('.')[col('.') - 1] == a:char
    return "\<Right>"
  else
    return a:char
  endif
endf

function CloseBracket()
  if match(getline(line('.') + 1), '\s*}') < 0
    return "\<CR>}"
  else
    return "\<ESC>j0f}a"
  endif
endf

function QuoteDelim(char)
  let line = getline('.')
  let col = col('.')
  if line[col - 2] == "\\"
    "Inserting a quoted quotation mark into the string
    return a:char
  elseif line[col - 1] == a:char
    "Escaping out of the string
    return "\<Right>"
  else
    "Starting a string
    return a:char.a:char."\<ESC>i"
  endif
endf
[email protected], September 24, 2004 5:44
Thisone is nice if one uses Perl:<br />
<pre>inoremap {<CR> {<CR>}<ESC>ko</pre>
this will not add the closing bracket if you type something like '$foo{"bar"}++', but it will help if you make subs or multiline hashes.
farooqym AT ieee.org, October 26, 2004 5:31
In Breadman's cool script you might want to add a TAB to the third line thusly
inoremap { {<CR>}<ESC>O <TAB>

so when u hit {  u will have
{
         |<-------cursor
}
Anonymous, October 19, 2006 1:47
Awesome! But, does anyone know how we can disable these automatic insertions between quotation marks, for example?
If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to [email protected] after searching the archive. Help Bram help Uganda.
   
Sponsored by Web Concept Group Inc. SourceForge.net Logo