I got this from voyeg3r's gist He and @dave-kennedy made it 3 years ago. I am here because I couldn't contact them

Can someone help me add a feature such that this vimscript code puts comment out signs at the first of each line?

let s:comment_map = {
    \   "c": '\/\/',
    \   "cpp": '\/\/',
    \   "go": '\/\/',
    \   "java": '\/\/',
    \   "javascript": '\/\/',
    \   "lua": '--',
    \   "scala": '\/\/',
    \   "php": '\/\/',
    \   "python": '#',
    \   "ruby": '#',
    \   "rust": '\/\/',
    \   "sh": '#',
    \   "desktop": '#',
    \   "fstab": '#',
    \   "conf": '#',
    \   "profile": '#',
    \   "bashrc": '#',
    \   "bash_profile": '#',
    \   "mail": '>',
    \   "eml": '>',
    \   "bat": 'REM',
    \   "ahk": ';',
    \   "vim": '"',
    \   "tex": '%',
    \ }

function! ToggleComment()
    if has_key(s:comment_map, &filetype)
        let comment_leader = s:comment_map[&filetype]
        if getline('.') =~ '^\s*$'
            " Skip empty line
        if getline('.') =~ '^\s*' . comment_leader
            " Uncomment the line
            execute 'silent s/\v\s*\zs' . comment_leader . '\s*\ze//'
            " Comment the line
            execute 'silent s/\v^(\s*)/\1' . comment_leader . ' /'
        echo "No comment leader found for filetype"

nnoremap <Leader>t :call ToggleComment()<CR>
vnoremap <Leader>t :call ToggleComment()<CR>

PS: this works perfectly. But i need the extra feature which will put comment out signs at the first of each line

for example: if i comment out this code

     #include <iostream>
using namespace std;

                          int main() {
    cout << "hello world" << "\n";

it will be like this

//     #include <iostream>
//using namespace std;

//                          int main() {
//    cout << "hello world" << "\n";
//             }
  • I'm not sure what you mean by 'comment out signs at the first of each line'. Could you add some example code with how the plugin puts the comments signs and a second example of how you would like them to be? Thanks! (P.S. I'm not sure if this solves your problem, but there is a plugin for commenting)
    – mattb
    Jul 3 at 8:21
  • sorry.. its not a plugin.. just custom code in vimrc.. updated the post.. please check
    – Mega Bang
    Jul 3 at 8:49
  • 1
    Hi, I'm still confused as you say it 'works perfectly' but you want to add a feature. So my question is what does the vimrc code do currently? Also the plugin I mentioned in the last comment does what you're trying to do here - it gives the gc operator to toggle the commenting one lines, and you can use it with any motion e.g. gcip to comment inside paragraph, or gc5j to comment current line and also 5 lines below.
    – mattb
    Jul 3 at 9:02
  • i meant.. my vimrc comment out code works fine.. but it lacks the feature of putting the comment out signs at the very first of each line
    – Mega Bang
    Jul 4 at 13:13

I think you need to change

            " Comment the line
            execute 'silent s/\v^(\s*)/\1' . comment_leader . ' /'


            " Comment the line
            execute 'silent s/^/\1' . comment_leader . '/'

so that it substitutes at the beginning of the line rather than after any space. The uncomment pattern needs similar modifications: replace \v\s*\zs with ^, and remove \s*\ze entirely.

For extra niceness, use escape(comment_leader, '/\') in the substitute commands; then the configuration doesn't need to escape the slashes.

  • your code works but it causes indentation error.. it puts comment out signs at the very first. it's true.. when i uncomment certain lines, it deletes indentation before each line & pulls the whole line or block of code at the first respectively
    – Mega Bang
    Jul 4 at 13:20
  • The uncomment probably needs to be adjusted. Try replacing \v\s*\zs with ^ and remove the \s*\ze
    – D. Ben Knoble
    Jul 4 at 13:22
  • it works.. thank you very much :)
    – Mega Bang
    Jul 4 at 13:25
  • my code needs some fix.. it doesn't support conf, mail, tex and so on.. i mean it doesn't comment out these files
    – Mega Bang
    Jul 4 at 13:30
  • @MegaBang you probably should ask a new question. Try using :debug if you can. And make sure you post details on the steps you take, what happens, and what you expect.
    – D. Ben Knoble
    Jul 4 at 13:31

It might be worth a mention that you can also visually select the lines and then do:

:'<,'>norm I// 

to apply the normal mode command Insert at the start of the line the commenting out characters (and remember to put a space after: // )

Without visual selection you could use line addresses:

" comment lines 10 through 20 
:10,20norm I// 
" comment relative lines -10 through +20
:-10,+20norm I// 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.