Vim Tips Wiki
Register
(Move categories to tip template)
(Remove html character entities)
 
Line 24: Line 24:
 
then substituting 'getline(".")', use 'getline(line(".") - 1)' should work.
 
then substituting 'getline(".")', use 'getline(line(".") - 1)' should work.
   
Put the following in your .vimrc:
+
Put the following in your [[vimrc]]:
 
<pre>
 
<pre>
au BufNewFile,BufRead *.c,*.cc,*.C,*.h imap } &lt;ESC&gt;:call CurlyBracket()&lt;CR&gt;a
+
au BufNewFile,BufRead *.c,*.cc,*.C,*.h imap } <Esc>:call CurlyBracket()<CR>a
   
 
function CurlyBracket()
 
function CurlyBracket()
Line 32: Line 32:
 
iunmap }
 
iunmap }
 
sil exe "normal i}"
 
sil exe "normal i}"
imap } &lt;ESC&gt;:call CurlyBracket()&lt;CR&gt;
+
imap } <Esc>:call CurlyBracket()<CR>
 
let l:result1 = searchpair('{', '', '}', 'bW')
 
let l:result1 = searchpair('{', '', '}', 'bW')
if (result1 &gt; 0)
+
if (result1 > 0)
 
let l:my_string = substitute(getline("."), '^\s*\(.*\){', '\1', "")
 
let l:my_string = substitute(getline("."), '^\s*\(.*\){', '\1', "")
 
sil exe ":" . l:my_linenum
 
sil exe ":" . l:my_linenum
Line 57: Line 57:
   
 
[4] I've added the line
 
[4] I've added the line
au BufNewFile,BufRead *.java,*.c,*.cc,*.C,*.h map &lt;A-F1&gt; :call CurlyBracket()&lt;CR&gt;
+
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.
 
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.
   
Line 65: Line 65:
 
iunmap }
 
iunmap }
 
sil exe "normal i}"
 
sil exe "normal i}"
imap } &lt;ESC&gt;:sil call CurlyBracket()&lt;CR&gt;a
+
imap } <Esc>:sil call CurlyBracket()<CR>a
 
let result1=searchpair('{', '', '}', 'bW')
 
let result1=searchpair('{', '', '}', 'bW')
 
let goline=""
 
let goline=""
 
let appendstr=""
 
let appendstr=""
if (result1 &gt; 0)
+
if (result1 > 0)
 
let l:my_startline=line(".")
 
let l:my_startline=line(".")
if (l:my_linenum - l:my_startline &gt; 10)
+
if (l:my_linenum - l:my_startline > 10)
 
let l:my_string=substitute(getline(line(".")-1),"^ *","","g")
 
let l:my_string=substitute(getline(line(".")-1),"^ *","","g")
 
let l:shortstring=strpart(l:my_string,0,30)."..."
 
let l:shortstring=strpart(l:my_string,0,30)."..."
Line 86: Line 86:
 
Okay. I have changed this script. It takes into account the last note and some other things I noticed.
 
Okay. I have changed this script. It takes into account the last note and some other things I noticed.
   
# This was annoying when I had a short if(){}else{} statement, so I changed the mapping to }&lt;CR&gt;.
+
# This was annoying when I had a short if(){}else{} statement, so I changed the mapping to }<CR>.
 
# If there is an else statement, the comment inserted is the if statement. followed by an else {
 
# If there is an else statement, the comment inserted is the if statement. followed by an else {
# &gt;10 lines check put in.
+
# >10 lines check put in.
# &lt; 30 char check put in
+
# < 30 char check put in
   
 
Notes:
 
Notes:
Line 96: Line 96:
   
 
<pre>
 
<pre>
au BufNewFile,BufRead *.c,*.cc,*.C,*.h imap }&lt;CR&gt; &lt;ESC&gt;:call CurlyBracket()&lt;CR&gt;a
+
au BufNewFile,BufRead *.c,*.cc,*.C,*.h imap }<CR> <Esc>:call CurlyBracket()<CR>a
   
 
function CurlyBracket()
 
function CurlyBracket()
 
let l:startline = line(".")
 
let l:startline = line(".")
 
let l:result1 = searchpair('{', '', '}', 'bW', '')
 
let l:result1 = searchpair('{', '', '}', 'bW', '')
if (result1 &gt; 0)
+
if (result1 > 0)
 
let l:linenum = line(".")
 
let l:linenum = line(".")
 
let l:string1 = getline(l:linenum)
 
let l:string1 = getline(l:linenum)
Line 107: Line 107:
 
sil exe "normal 0"
 
sil exe "normal 0"
 
let l:result2 = searchpair('{', '', '}', 'bW', '')
 
let l:result2 = searchpair('{', '', '}', 'bW', '')
if (l:result2 &gt; 0)
+
if (l:result2 > 0)
 
let l:string1 = getline(".") . l:string1
 
let l:string1 = getline(".") . l:string1
 
endif
 
endif
Line 115: Line 115:
 
sil exe ":" . l:startline
 
sil exe ":" . l:startline
 
sil exe "normal i}"
 
sil exe "normal i}"
if ((l:startline - l:linenum) &gt; 10)
+
if ((l:startline - l:linenum) > 10)
 
sil exe "normal a //" . l:my_string
 
sil exe "normal a //" . l:my_string
 
endif
 
endif
Line 151: Line 151:
 
[2] The number of lines is taken form the start of the "if" (in case of if-else)
 
[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 &gt; 30.
+
[3] The "..." is added only if the length of the stringis > 30.
   
 
=======
 
=======
Line 159: Line 159:
 
" Automatically comments {} in C/C++/Java.
 
" Automatically comments {} in C/C++/Java.
   
au BufNewFile,BufRead *.c,*.cc,*.h imap }&lt;CR&gt; &lt;ESC&gt;:call CurlyBracket()&lt;CR&gt;a
+
au BufNewFile,BufRead *.c,*.cc,*.h imap }<CR> <Esc>:call CurlyBracket()<CR>a
au BufNewFile,BufRead *.cpp,*.C imap }&lt;CR&gt; &lt;ESC&gt;:call CurlyBracket()&lt;CR&gt;a
+
au BufNewFile,BufRead *.cpp,*.C imap }<CR> <Esc>:call CurlyBracket()<CR>a
au BufNewFile,BufRead *.java,*.idl imap }&lt;CR&gt; &lt;ESC&gt;:call CurlyBracket()&lt;CR&gt;a
+
au BufNewFile,BufRead *.java,*.idl imap }<CR> <Esc>:call CurlyBracket()<CR>a
   
 
function CurlyBracket()
 
function CurlyBracket()
 
let l:startline = line(".")
 
let l:startline = line(".")
 
let l:result1 = searchpair('{', '', '}', 'bW')
 
let l:result1 = searchpair('{', '', '}', 'bW')
if (result1 &gt; 0)
+
if (result1 > 0)
 
let l:linenum = line(".")
 
let l:linenum = line(".")
 
let l:string1 = substitute(getline(l:linenum), '^\s*\(.*\)\s*$', '\1', "")
 
let l:string1 = substitute(getline(l:linenum), '^\s*\(.*\)\s*$', '\1', "")
Line 178: Line 178:
 
sil exe "normal 0"
 
sil exe "normal 0"
 
let l:result2 = searchpair('{', '', '}', 'bW')
 
let l:result2 = searchpair('{', '', '}', 'bW')
if (l:result2 &gt; 0)
+
if (l:result2 > 0)
 
let l:linenum = line(".")
 
let l:linenum = line(".")
 
let l:string2 = substitute(getline(l:linenum), '^\s*\(.*\)\s*$', '\1', "")
 
let l:string2 = substitute(getline(l:linenum), '^\s*\(.*\)\s*$', '\1', "")
Line 191: Line 191:
 
let l:my_string = substitute(l:string1, '\s*{[^{]*$', '', "")
 
let l:my_string = substitute(l:string1, '\s*{[^{]*$', '', "")
 
let l:my_strlen = strlen(l:my_string)
 
let l:my_strlen = strlen(l:my_string)
if (l:my_strlen &gt; 30)
+
if (l:my_strlen > 30)
 
let l:my_string = strpart(l:my_string,0,30)."..."
 
let l:my_string = strpart(l:my_string,0,30)."..."
 
endif
 
endif
Line 197: Line 197:
 
sil exe ":" . l:startline
 
sil exe ":" . l:startline
 
sil exe "normal i}"
 
sil exe "normal i}"
if ((l:startline - l:linenum) &gt; 10)
+
if ((l:startline - l:linenum) > 10)
 
sil exe "normal a /* " . l:my_string . " */"
 
sil exe "normal a /* " . l:my_string . " */"
 
endif
 
endif
Line 218: Line 218:
   
 
----
 
----
People facing Problems with running this script can try removing the &lt;space&gt; after "iunmap }" statement.
+
People facing Problems with running this script can try removing the <Space> after "iunmap }" statement.
   
 
----
 
----

Latest revision as of 08:30, 28 September 2008

Tip 125 Printable Monobook Previous Next

created October 2, 2001 · complexity basic · author Long Truong · version 6.0


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[]

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.

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

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

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.

=[]

" 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

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:
 ...

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


If you are deciding which script to use, I used curlyC.vim.

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


The 10 lines buffer was deliberate - you don't want the closing comments for small blocks