mizlan / vim-and-cp

Some helpful bits and pieces for your vimrc
42 stars 12 forks source link

Multiple filetypes comment out feature #4

Closed j0k4rX closed 3 years ago

j0k4rX commented 3 years ago
function! CommentToggle()
    execute ':silent! s/\([^ ]\)/\/\/ \1/'
    execute ':silent! s/^\( *\)\/\/ \/\/ /\1/'
endfunction
map <C-C> :call CommentToggle()<CR>

This block of code has a specific feature that i need to implement in my init.vim code (given below) It puts the comment out signs at the first of each line.

for example: If I comment out this cpp code, it puts the comment out sign at the very first of each line this is the expected behavior of my init.vim code

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

// int main() {
//     int a, b, c;
//     cin >> a >> b >> c;
//     cout << a+b+c << "\n";
// }

But commenting out for different filetypes like lua files, this code will put // not -- which is wrong.


My init.vim code ```vim 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 return endif if getline('.') =~ '^\s*' . comment_leader " Uncomment the line execute 'silent s/\v\s*\zs' . comment_leader . '\s*\ze//' else " Comment the line execute 'silent s/\v^(\s*)/\1' . comment_leader . ' /' endif else echo "No comment leader found for filetype" endif endfunction nnoremap :call ToggleComment() vnoremap :call ToggleComment() ```


Current behavior of my init.vim code

my init.vim code puts respective comment out signs for each mentioned filetypes. But the problem is: it doesn't put comment out signs at the very first of each line

instead it does this.. see 5-7 lines

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

// int main() {
     // int a, b, c;
     // cin >> a >> b >> c;
     // cout << a+b+c << "\n";
// }

it should be like the previous cpp example code

mizlan commented 3 years ago

So to confirm, you're not using a commenting plugin right? Just the above code.

This is a regex question, I'll take a look when I get on desktop.

mizlan commented 3 years ago

I dug up this thread, which is where you got the code from: https://gist.github.com/voyeg3r/223f148a115c17a02a15660cc7335f4c

See if the following change works:

diff --git a/a.vim b/b.vim
index 17be639..d3c6330 100644
--- a/a.vim
+++ b/b.vim
@@ -37,7 +37,7 @@ function! ToggleComment()
             execute 'silent s/\v\s*\zs' . comment_leader . '\s*\ze//'
         else
             " Comment the line
-            execute 'silent s/\v^(\s*)/\1' . comment_leader . ' /'
+            execute 'silent s/\v^(\s*)/' . comment_leader . '\1 /'
         endif
     else
         echo "No comment leader found for filetype"

All I'm doing is adding leading whitespace after the comment symbol, instead of before it.

j0k4rX commented 3 years ago

So to confirm, you're not using a commenting plugin right? Just the above code.

This is a regex question, I'll take a look when I get on desktop.

yep that's correct

j0k4rX commented 3 years ago

I dug up this thread, which is where you got the code from: https://gist.github.com/voyeg3r/223f148a115c17a02a15660cc7335f4c

See if the following change works:

diff --git a/a.vim b/b.vim
index 17be639..d3c6330 100644
--- a/a.vim
+++ b/b.vim
@@ -37,7 +37,7 @@ function! ToggleComment()
             execute 'silent s/\v\s*\zs' . comment_leader . '\s*\ze//'
         else
             " Comment the line
-            execute 'silent s/\v^(\s*)/\1' . comment_leader . ' /'
+            execute 'silent s/\v^(\s*)/' . comment_leader . '\1 /'
         endif
     else
         echo "No comment leader found for filetype"

All I'm doing is adding leading whitespace after the comment symbol, instead of before it.

you are a genius.. It worked :)

j0k4rX commented 3 years ago

@mizlan there's been a problem. When i uncomment this cpp code, the normal indents vanishes.

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

// int main() {
//     int a, b, c;
//     cin >> a >> b >> c;
//     cout << a+b+c << "\n";
// }

Current Behavior it uncomments & turns the code into this.. see 5-7 lines the lines are dragged to the start of each line

#include <iostream>
using namespace std;

int main(){
int a, b, c, sum;
cin >> a >> b >> c;
cout << a+b+c << "\n";
}


Expected behavior:

int main(){
    int a, b, c, sum;
    cin >> a >> b >> c;
    cout << a+b+c << "\n";
}
mizlan commented 3 years ago

Send me what your current code is.

mizlan commented 3 years ago

Try this:

diff --git a/a.vim b/b.vim
index d3c6330..ef3ed28 100644
--- a/a.vim
+++ b/b.vim
@@ -34,7 +34,7 @@ function! ToggleComment()
         endif
         if getline('.') =~ '^\s*' . comment_leader
             " Uncomment the line
-            execute 'silent s/\v\s*\zs' . comment_leader . '\s*\ze//'
+            execute 'silent s/\v\zs\s*' . comment_leader . '\ze\s*//'
         else
             " Comment the line
             execute 'silent s/\v^(\s*)/' . comment_leader . '\1 /'
j0k4rX commented 3 years ago

sorry.. I was taking an online exam from college this works but it's putting a space at the start of each line everytime when i uncomment the code

current code:

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
            return
        endif
        if getline('.') =~ '^\s*' . comment_leader
            " Uncomment the line
            " execute 'silent s/\v\s*\zs' . comment_leader . '\s*\ze//'
        execute 'silent s/\v\zs\s*' . comment_leader . '\ze\s*//'
        else
            " Comment the line
            " execute 'silent s/\v^(\s*)/\1' . comment_leader . ' /'
        execute 'silent s/\v^(\s*)/' . comment_leader . '\1 /'
        endif
    else
        echo "No comment leader found for filetype"
    endif
endfunction

nnoremap <C-C> :call ToggleComment()<CR>
vnoremap <C-C> :call ToggleComment()<CR>
mizlan commented 3 years ago
diff --git a/a.vim b/b.vim
index ef3ed28..6ea5009 100644
--- a/a.vim
+++ b/b.vim
@@ -34,7 +34,7 @@ function! ToggleComment()
         endif
         if getline('.') =~ '^\s*' . comment_leader
             " Uncomment the line
-            execute 'silent s/\v\zs\s*' . comment_leader . '\ze\s*//'
+            execute 'silent s/\v\zs\s*' . comment_leader . ' ?\ze\s*//'
         else
             " Comment the line
             execute 'silent s/\v^(\s*)/' . comment_leader . '\1 /'
j0k4rX commented 3 years ago

The code is half-working now.. It puts two extra spaces in normal indentation (in line 5-7)

#include <iostream>
using namespace std;

int main() {
     int a, b;
     cin >> a >> b;
     cout << a+b << "\n";
}
mizlan commented 3 years ago

You're not being very descriptive, what is "It"? What is "normal indentation"? What is an extra space? I only see one extra space, not two. I don't think this is worth digging any deeper, especially because there are some unresolvable situations. I'd recommend you use a plugin like vim-commentary instead.

j0k4rX commented 3 years ago

I tried vim-commentary plugin.. it comments out blank lines

if you just try this code, i want the exact same thing for multiple filetypes. this code just have // sign.

function! CommentToggle()
    execute ':silent! s/\([^ ]\)/\/\/ \1/'
    execute ':silent! s/^\( *\)\/\/ \/\/ /\1/'
endfunction
map <C-C> :call CommentToggle()<CR>
mizlan commented 3 years ago

I tried vim-commentary plugin.. it comments out blank lines

No, it does not.

this code just have // sign.

Do you want comments to be followed by a space? e.g.,

example

becomes

// example

instead of

//example
j0k4rX commented 3 years ago

I want comments to be followed by a space

#include<iostream>
using namespace std;

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    cout << a+b+c << "\n";
}

becomes

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

//int main() {
//    int a, b, c;
//    cin >> a >> b >> c;
//    cout << a+b+c << "\n";
// }

instead of

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

// int main() {
//     int a, b, c;
//     cin >> a >> b >> c;
//     cout << a+b+c << "\n";
// }
mizlan commented 3 years ago

So you don't want the space? I am very busy with work right now, I highly recommend you use vim-commentary.

j0k4rX commented 3 years ago

your latest code fix, does this code with tabwidth 4

1234int a, b, c;
1234cin >> a >> b >> c;
1234cout << a+b+c << "\n";

into this (extra 1 or 2 spaces)

12345int a, b, c;
12345cin >> a >> b >> c;
12345cout << a+b+c << "\n";
j0k4rX commented 3 years ago

So you don't want the space? I am very busy with work right now, I highly recommend you use vim-commentary.

I even asked this same question in vi.stackexchange, stackoverflow they at first looked at my code then totally ignored it

you were my last hope

I just wanted the comment out signs at the start of each line but in return, there is always spacing problem

j0k4rX commented 3 years ago

here's the thread https://vi.stackexchange.com/questions/31736/how-can-i-change-this-comment-plugin-to-work-at-the-start-of-the-line?noredirect=1#comment58362_31736

mizlan commented 3 years ago

The issue is you have no clue what you're doing with the code. You need to learn what it's doing and tune it to your liking, because you're not very good at describing your problem. That is what I suggest.