views:

38

answers:

2

I have a simple goal: Map Ctrl-C, a command I don't think I've ever used to kill vim, to automatically insert at the beginning of a line the correct character(s) to comment out that line according to the file's filetype.

I figured I could use an autocommand the recognize the file type and set a vim variable to the correct comment character when the file is open. So I tried something like:

" Control C, which is NEVER used. Now comments out lines!
autocmd BufNewFile,BufRead *.c let CommentChar = "//"
autocmd BufNewFile,BufRead *.py let CommentChar = "#"
map <C-C> mwI:echo &CommentChar<Esc>`wll

That map marks my current location, goes to the beginning of the line in insert mode, echoes the Comment Character(s) at that point, enters command mode, goes back to the set mark, and goes two characters right to make up for the inserted comment characters (assuming C style comment).

The italicized portion is the part I'm having trouble with; it is only there as a place holder to represent what I want to do. Can you help me figure out how to achieve this? Bonus points if you use strlen(CommentChar) to step the correct number of spaces to the right! Extra bonus points for the vim-master that includes how to do block-style comments if you are in visual mode!!

I'm still fairly new at vim scripting; my .vimrc is a measly 98 lines long, so if you could please help me by explaining any answers you provide! Thanks.

+3  A: 

You can use <C-r> here:

noremap <C-c> mwI<C-r>=g:CommentChar<CR><Esc>`wll

see :h i_CTRL-R.

Also look at NERDCommenter plugin, with it mapping will look like this:

" By default, NERDCommenter uses /* ... */ comments for c code.
" Make it use // instead
let NERD_c_alt_style=1
noremap <C-c> :call NERDComment(0, "norm")<CR>

And you will not have to define comment characters by yourself.

ZyX
the `=` register is awesome :)
Benoit
Thanks for explaining it all. I had read about i_CTRL-R but hadn't comprehended it. Thanks to you I've gotten my little script to work (but changed `wll to `w:exe "normal ".strlen(CommentChar)."l"<CR> to get the cursor back in the right spot). Also thanks to you, I abandoned my script and am now using NERDCommenter! But at least I've learned some more about vim in the process.
vgm64
+1  A: 

I pulled this off the vim tips wiki at some point and use it myself. The only downside is it adds a space to the end of the line(s) for some reason, probably something small I overlooked.

" Set comment characters for common languages
autocmd FileType python,sh,bash,zsh,ruby,perl,muttrc let StartComment="#" | let EndComment=""
autocmd FileType html let StartComment="<!--" | let EndComment="-->"
autocmd FileType php,cpp,javascript let StartComment="//" | let EndComment=""
autocmd FileType c,css let StartComment="/*" | let EndComment="*/"
autocmd FileType vim let StartComment="\"" | let EndComment=""
autocmd FileType ini let StartComment=";" | let EndComment=""

" Toggle comments on a visual block
function! CommentLines()
    try
        execute ":s@^".g:StartComment." @\@g"
        execute ":s@ ".g:EndComment."$@@g"
    catch
        execute ":s@^@".g:StartComment." @g"
        execute ":s@$@ ".g:EndComment."@g"
    endtry
endfunction

" Comment conveniently
vmap <Leader>c :call CommentLines()<CR>
Randy Morris
Thanks for the StartComment and EndComment mindset. That will be useful for other tasks, too.
vgm64