Vim Tips Wiki
Advertisement

Previous TipNext Tip

Tip: #125 - Comment your code blocks automatically

Created: October 2, 2001 6:48 Complexity: basic Author: Long Truong Version: 6.0 Karma: 55/22 Imported from: Tip#125

I always wanted a script that would auto-comment the end of a conditional block. So, I wrote one. This function searches for the previous matching "{", grabs the line, and inserts it as a comment after the "}". If there is no previous matching "{", it inserts nothing. So...

if (test){ 

will generate:

} // if (test) 

This is obviously not work if you use a different style. If you use

if (test) 
{ 

then substituting 'getline(".")', use 'getline(line(".") - 1)' should work.

Put the following in your .vimrc:

 au BufNewFile,BufRead *.c,*.cc,*.C,*.h imap } <ESC>:call CurlyBracket()<CR>a 

function CurlyBracket() 
  let l:my_linenum = line(".") 
  iunmap } 
  sil exe "normal i}" 
  imap } <ESC>:call CurlyBracket()<CR> 
  let l:result1 = searchpair('{', '', '}', 'bW') 
  if (result1 > 0) 
    let l:my_string = substitute(getline("."), '^\s*\(.*\){', '\1', "") 
    sil exe ":" . l:my_linenum 
    sil exe "normal a //" . l:my_string 
  endif 
 endfunction

Comments

sweet! thanks for a great tip!

octorock--AT--doubtful.com , October 2, 2001 8:34


Thanks for the cool script. I had some problems getting it working, but I've bodged it for now. Don't know if you're interested, but I've made a few modifications.

[1] Works for

if (x ==1 ) 
{ 
..... 
} 

(the substitution appeared to be going awry for lines with braces on their own)

[2] Won't comment lines that are within 10 lines of each other. I find this script great for big huge functions, but for short if statements it can quickly clog up the code with obvious comments.

[3] Won't copy the entire line, but truncates at 30 characters. Prepended spaces are removed.

[4] I've added the line

au BufNewFile,BufRead *.java,*.c,*.cc,*.C,*.h map <A-F1> :call CurlyBracket()<CR> 

to my .vimrc for those times when you started with a small if statement, and ended up with a mammoth one. Simply calls CurleyBracket to comment it.

Hope you don't mind my additions to such a useful script

N.

function! CurlyBracket() 
 let l:my_linenum=line(".") 
 iunmap } 
 sil exe "normal i}" 
 imap } <ESC>:sil call CurlyBracket()<CR>a 
 let result1=searchpair('{', '', '}', 'bW') 
 let goline="" 
 let appendstr="" 
 if (result1 > 0) 
 let l:my_startline=line(".") 
 if (l:my_linenum - l:my_startline > 10) 
 let l:my_string=substitute(getline(line(".")-1),"^ *","","g") 
 let l:shortstring=strpart(l:my_string,0,30)."..." 
 let appendstr="normal a // ".shortstring 
 endif 
 let goline=":".l:my_linenum 
 endif 
 sil exe goline 
 sil exe appendstr 
endfunction

Anonymous , October 3, 2001 10:36


Okay. I have changed this script. It takes into account the last note and some other things I noticed.

  1. This was annoying when I had a short if(){}else{} statement, so I changed the mapping to }<CR>.
  2. If there is an else statement, the comment inserted is the if statement. followed by an else {
  3. >10 lines check put in.
  4. < 30 char check put in

Notes:

  • This will not indent correctly unless you're using cindent. For some reason, a friend of mine with smartindent and it didn't work
  • If your style is to put the curly bracket on it's own line after the "if", add "-1" to all the getline calls.
au BufNewFile,BufRead *.c,*.cc,*.C,*.h imap }<CR> <ESC>:call CurlyBracket()<CR>a 

function CurlyBracket() 
 let l:startline = line(".") 
 let l:result1 = searchpair('{', '', '}', 'bW', '') 
 if (result1 > 0) 
 let l:linenum = line(".") 
 let l:string1 = getline(l:linenum) 
 if (l:string1 =~ ".*}.*{.*") 
 sil exe "normal 0" 
 let l:result2 = searchpair('{', '', '}', 'bW', '') 
 if (l:result2 > 0) 
 let l:string1 = getline(".") . l:string1 
 endif 
 endif 

 let l:my_string = substitute(l:string1, '^\s*\(.*\){', '\1', "") 
 let l:my_string = strpart(l:my_string,0,30)."..." 
 sil exe ":" . l:startline 
 sil exe "normal i}" 
 if ((l:startline - l:linenum) > 10) 
 sil exe "normal a //" . l:my_string 
 endif 
 endif 
endfunction 

Long Truong , October 3, 2001 11:49


Hi! I tried this script (and also the second) and get the following errors when entering a }. Seems like it's stuck in recursion... :-( This happens with Vim 6.0final on Linux and Windoze...

Any Ideas?

J�rg

Error detected while processing function CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..Curly 
Bracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..Curly 
Bracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..Curly 
Bracket..CurlyBracket..CurlyBracket: 
line 2: 
E31: No such mapping 

jhm--AT--gmx.net , October 4, 2001 10:46


Hi,

Just 3 modifications:

[1]. Now, supports both styles of

if (..) { 
 .. 
} 

and

if (...) 
{ 
 ... 
} else 
{ 
 ... 
} 

but,

if () 
{ 
} 
else 
{ 
}

still does not work!!

[2] The number of lines is taken form the start of the "if" (in case of if-else)

[3] The "..." is added only if the length of the stringis > 30.

regards Sameer.

=

" curlyC.vim 
" From Long Truong : Vim Tip #125. 
" Automatically comments {} in C/C++/Java. 

au BufNewFile,BufRead *.c,*.cc,*.h imap }<CR> <ESC>:call CurlyBracket()<CR>a 
au BufNewFile,BufRead *.cpp,*.C imap }<CR> <ESC>:call CurlyBracket()<CR>a 
au BufNewFile,BufRead *.java,*.idl imap }<CR> <ESC>:call CurlyBracket()<CR>a 

function CurlyBracket() 
 let l:startline = line(".") 
 let l:result1 = searchpair('{', '', '}', 'bW') 
 if (result1 > 0) 
 let l:linenum = line(".") 
 let l:string1 = substitute(getline(l:linenum), '^\s*\(.*\)\s*$', '\1', "") 
 if (l:string1 =~ '^{') 
 let l:string1 = substitute(getline(l:linenum - 1), '^\s*\(.*\)\s*$', '\1', "") . " " . l:string1 
 sil exe "normal k" 
 endif 

 " get else part if necessary 
 if (l:string1 =~ "^}") 
 sil exe "normal 0" 
 let l:result2 = searchpair('{', '', '}', 'bW') 
 if (l:result2 > 0) 
 let l:linenum = line(".") 
 let l:string2 = substitute(getline(l:linenum), '^\s*\(.*\)\s*$', '\1', "") 
 if (l:string2 =~ '^{') 
 let l:string2 = substitute(getline(l:linenum - 1), '^\s*\(.*\)\s*$', '\1', "") . " " . l:string2 
 endif 
 let l:string1 = l:string2 . " ... " . l:string1 
 endif 
 endif 

 " remove trailing whitespaces and curly brace 
 let l:my_string = substitute(l:string1, '\s*{[^{]*$', '', "") 
 let l:my_strlen = strlen(l:my_string) 
 if (l:my_strlen > 30) 
 let l:my_string = strpart(l:my_string,0,30)."..." 
 endif 

 sil exe ":" . l:startline 
 sil exe "normal i}" 
 if ((l:startline - l:linenum) > 10) 
 sil exe "normal a /* " . l:my_string . " */" 
 endif 

 endif 
endfunction 

schabungbam--AT--hss.hns.REMOVEME.com , October 20, 2001 1:34


I use: vim6.1.74 - Linux Nice tip but it doesn't work for me!

Error detected while processing function CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..Curly 
Bracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..Curly 
Bracket..CurlyBracket: 
line 2: 
 Error detected while processing function CurlyBracket..CurlyBracket..CurlyBracket..CurlyBr 
acket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..CurlyBracket..Curly 
Bracket..CurlyBracket..CurlyBracket: 
line 2: 
E31: No such mapping

pacman--AT--huji.ac.il , June 26, 2002 3:42


Peopple facing Problems with running this script can try removing the <space> after "iunmap }" statement.


Pankaj


panjwani_pankaj--AT--yahoo.com , July 15, 2004 3:34


If you are deciding which script to use, I used the one by

schabungbam--AT--hss.hns.REMOVEME.com, October 20, 2001 1:34

and it works nicely for me.

Remember that completion is done only if { and } are separated by 10 lines

VIKAS GUPTA , September 13, 2006 22:20


schabungbam--AT--hss.hns.REMOVEME.com is now schabungbam--AT--gmail

The 10 lines buffer was deliberate - you dont want the closing comments for small blocks

schabungbam--AT--gmail DOT com , December 12, 2006 12:15


Advertisement