sponsor Vim development Vim logo Vim Book Ad

intermediate Tip #855: Automatically add closing brace to block when coding

 tip karma   Rating 22/7, Viewed by 2445 

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

created:   January 18, 2005 3:13      complexity:   intermediate
author:   Richard Willis      as of Vim:   6.0

I got fed up with having to add the closing brace to a code block, so I've got my Vim to automatically add a closing brace when coding in c#. Add the following to any appropriate ftplugin files (prefereably in vimfiles/ftplugin) so they don't get overwritten on upgrades.

The script will automatically add the closing brace and position the cursor on a line between the opening and closing braces. It ignores braces in comments, strings and if the word new is in the line (e.g. for string[] myArray = new string[] {"a", "b"}.

There are maps for enclosing code in a set of braces.

imap { <esc>:call ReplaceCurly()<Cr>cl

function! ReplaceCurly()
    imap { {
    " only replace outside of comments or strings (which map to constant)
    let elesyn = synIDtrans(synID(line("."), col(".") - 1, 0))
    if elesyn != hlID('Comment') && elesyn != hlID('Constant') && match(getline("."), "\\<new\\>") < 0
      exe "normal a{"
      " need to add a spare character (x) to position the cursor afterwards
      exe "normal ox"
      exe "normal o}"
      exe "normal kw"
    else
      " need to add a spare character (x) to position the cursor afterwards
      exe "normal a{x"
    endif
    imap { <esc>:let word= ReplaceCurly()<Cr>cl
endfunction

"Surround code with braces
nmap <leader>{} O{<esc>ddj>>ddkP
vmap <leader>{} <esc>o{<esc>ddgv>gvdp

 rate this tip  Life Changing Helpful Unfulfilling 

<< Write a dated backup of the current file. | syntax highlighting >>

Additional Notes

Richard Willis, January 18, 2005 8:00
Slight improvement.

Change both of the imap lines to

    imap { <esc>:let word= ReplaceCurly()<Cr>"_cl

(adding "_  before the cl at the end)

This avoids clobbering the unnamed register i.e. the one you use if you don't specify any.
Anonymous, January 19, 2005 3:11
I have some abbreviations for programming in C/C++, which will expand to a complete block
and position the cursor to the first item to be changed.

e.g.
   abb cfor for (i = 0 ; i < 0; i++)^M{^M} /* endfor */^M^[?for (^Mw
will insert a complete for-block at current cursor position and sets the cursor on the first 'i'.

^M is ctrl-v,ctrl-M
^[   is ctrl-v,escape

Thomas
hermitte {at} free {dot} fr, January 19, 2005 15:40
For a more advanced [1] and complete solution, you can have a look at my ftplugins for C & C++ [2].

[1] More advanced in the sense I support markers (placeholders in another terminology), several things can be easily tweaked (whether we want newlines or not before the curly-brackets, ...), the abbreviations are buffer-relative (which is necessary to have "for" expand into diffrent things according to the filetype of the buffer edited), ...

[2] http://hermitte.free.fr/vim/c.php
cbouvi <at> free <dot> fr, January 26, 2005 7:51
I solved this same problem differently.

What I wanted is to automatically insert a closing curly and be taken on a new line inside the block whenever I open a new block, i.e., whenever I type an opening curly and a newline. Manually, I'd have to do this:

    {<cr>
    }<esc>

Then, hit O to insert a new line before the closing curly, and go on typing. Thanks to the auto-indentation system, this new line would be properly indented.

What I do not want is to have a closing curly *always* inserted, because it sometimes happens that I want to surround an existing piece of code with curlies.

    {
    } # oops, automatically inserted, needs to be deleted later.
   existing piece of code

Or (and this is quite common in Perl), I want the block to stay on one line.

So I just remapped the sequence {<cr>

    inoremap {<cr> {<cr>}<esc>O

That's it. If I type anything other than return, or even if I wait too long after the opening curly, nothing special will happen.
cbouvi <at> free <dot> fr, January 26, 2005 7:51
I solved this same problem differently.

What I wanted is to automatically insert a closing curly and be taken on a new line inside the block whenever I open a new block, i.e., whenever I type an opening curly and a newline. Manually, I'd have to do this:

    {<cr>
    }<esc>

Then, hit O to insert a new line before the closing curly, and go on typing. Thanks to the auto-indentation system, this new line would be properly indented.

What I do not want is to have a closing curly *always* inserted, because it sometimes happens that I want to surround an existing piece of code with curlies.

    {
    } # oops, automatically inserted, needs to be deleted later.
   existing piece of code

Or (and this is quite common in Perl), I want the block to stay on one line.

So I just remapped the sequence {<cr>

    inoremap {<cr> {<cr>}<esc>O

That's it. If I type anything other than return, or even if I wait too long after the opening curly, nothing special will happen.
sarumont AT sigil DOT org, May 29, 2006 11:22
Comment above me was just what I was looking for.  I modified it to indent the code inside the block:

inoremap {<cr> {<cr>}<esc>O<tab>
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 the maillist. Help Bram help Uganda.
   
Sponsored by Web Concept Group Inc. SourceForge.net Logo