I am trying to add a keybinding for
function! g:toggleComment()
normal! gv
let startline = line("v")
let endline = line(".")
call VSCodeNotifyRange('editor.action.commentLine', startline, endline, 1)
endfunction
vnoremap <C-/> :call g:toggleComment()<cr>
But nothing happens when I press \
You need to use VSCodeNotifyRangePos instead, see this for reference or this
ah, excuse me, i mislook. it's right here
Try to use :<C-u>call g:toggleComment()<cr>
what does \
This still does not work.
Make sure you set: "args": "<C-/>" in vscode keybinding. VSCode keybinding UI doesn't copy args, i.e.
{
"command": "vscode-neovim.send",
"key": "ctrl+/",
"when": "editorTextFocus && neovim.init && neovim.mode != visual",
"args": "<C-/>"
},
what does
do?
Clears '<, '> marks from commandline. Shouldn't matter though
That's not the keybinding that I changed the when expression for. When I said it I didn't realize that it was a keybinding that I added myself :-). Anyway, I completely removed that one, but still nothing happens.
:verbose map <C-/> shows nothing.
function! g:toggleComment()
just noticed - that's not correct function name, it should start either with s: (for local functions, e.g. s:toggleComment()) or with capital, e.g. ToggleComment() . So your init.vim breaks that's why default <C-/> keymap doesn't work. Once you delete your function it should be fine.
:verbose and other commands that open multi-line pager (.e.g :reg, :changes, etc) don't work currently
Thank you so much! After changing g:toggleComment() to g:ToggleComment() (and xnoremap to vnoremap - not sure why xnoremap doesn't work), this works perfectly!
Ok, now I have another question. It's about something different but along the same lines, so I didn't think it would be necessary to open another issue, but I will if you want me to.
I'm working on two more functions - g:MoveLinesUp and g:MoveLinesDown - that will move visually selected lines up or down. The code is the same as g:ToggleComment() - the fixed version - except for the command. It works, but when the lines are moved, the selection stays on the lines that were previously selected instead of the code that was previously selected.
For example say you have the following code:
1. print("line 1")
2. print("line 2")
3. print("line 3")
Then you visually select lines 2 and 3, then call g:MoveLinesUp. Your code would look like this:
1. print("line 2")
2. print("line 3")
3. print("line 1")
but you would still be selecting lines 2 and 3 instead of lines 1 and 2.
How do I fix this?
note: I have the last argument of VSCodeNotifyRange as 0.
What it would have to do is move the visual selection whenever it moved the lines. So how do you move a visual line selection? Or exit visual mode and start a new one at the right place and the right size?
I think I figured out what should work, but it isn't. In vim typing :n
I'm moving the move visually selected lines problem to a new issue b/c I have another problem with toggling comments.
The problem is, line("v") always returns the highest part of the visual selection, and line(".") always returns the cursor position. So when the visual selection was made from the bottom up, these two functions return the same number, so only the line that the cursor is on gets commented out.
I'm moving the move visually selected lines problem to a new issue b/c I have another problem with toggling comments.
The problem is,
line("v")always returns the highest part of the visual selection, andline(".")always returns the cursor position. So when the visual selection was made from the bottom up, these two functions return the same number, so only the line that the cursor is on gets commented out.
That's something with your binding/function. Default <C-/> binding or vscodeCommentary doesn't suffer this problem
I think I figured out what should work, but it isn't. In vim typing :n where n is any number will take you to that line. This doesn't work in vscode-neovim. Why not?
works for me
It's working for me too now, I don't know why it wasn't before.
That's something with your binding/function. Default
binding or vscodeCommentary doesn't suffer this problem
What is vscodeCommentary anyway? When I tried :call vscodeCommentary I got "Unknown Function: vscodeCommentary"
Here's the function:
function! g:ToggleComment()
normal! gv
let selection = [getpos("'<"), getpos("'>")]
let endLine = selection[1][1]
let startLine = selection[0][1]
call VSCodeNotifyRange("editor.action.commentLine", startLine, endLine, 0)
endfunction
Here's the binding:
vnoremap <C-/> :<C-u>call g:ToggleComment()<cr>
Here's the weird thing. The binding \
That's something with your binding/function. Default binding or vscodeCommentary doesn't suffer this problem
What is vscodeCommentary anyway? When I tried
:call vscodeCommentaryI got "Unknown Function: vscodeCommentary"
It's analogue of vim-commentary plugin which uses vscode commentLine command. See this
It's mentioned in readme, the recommended bindings are:
xmap gc <Plug>VSCodeCommentary
nmap gc <Plug>VSCodeCommentary
omap gc <Plug>VSCodeCommentary
nmap gcc <Plug>VSCodeCommentaryLine
Works in operator pending mode too, e.g. gci{
Default <C-/> binding maps to this unless you've replaced it with something else
The problem is, line("v") always returns the highest part of the visual selection, and line(".") always returns the cursor position. So when the visual selection was made from the bottom up, these two functions return the same number, so only the line that the cursor is on gets commented out.
It's not true. line("v") returns the start line of a visual selection or the cursor position when not in visual mode.
If you still want to continue with your function try to remove normal! gv . Other option is to remove <C-u> from keybinding add range keyword to the function and use a:firstline and a:lastline
The problem is, line("v") always returns the highest part of the visual selection, and line(".") always returns the cursor position. So when the visual selection was made from the bottom up, these two functions return the same number, so only the line that the cursor is on gets commented out.
It's not true. line("v") returns the start line of a visual selection or the cursor position when not in visual mode.
Say you have three lines of code:
1. line 1
2. line 2
3. line 3
You put your cursor on line 3, press shift-v to enter visual line mode and press k twice. Now all three lines are selected with the cursor on line 1. Now type :let top = line("v") and press enter, then type :echo top and press enter. Displayed at the bottom is 1, even though the visual selection was started from line 3. This is what I meant when I said that it always returns the highest line. I would need it to return 3, not 1 for my function to work.
Now type :let top = line("v") and press enter, then type :echo top and press enter.
When you enter command mode the visual mode disappears and it returns current cursor pos what's why v doesn't give you correct results ;)
Please excuse my ignorance, but I would like to comment out a multi-line function in normal mode.
I can use ctrl - / to comment out a line, but how do you select the paragraph/block to comment out? I understand visual mode does not work for this... how is it done? I have never used actual VIM before, I don't know about function for it. Hoping there is a comment out paragraph shortcut built in. Thanks, amazing extension!
Please excuse my ignorance, but I would like to comment out a multi-line function in normal mode.
I can use
ctrl - /to comment out a line, but how do you select the paragraph/block to comment out? I understand visual mode does not work for this... how is it done? I have never used actual VIM before, I don't know about function for it. Hoping there is acomment out paragraphshortcut built in. Thanks, amazing extension!
Perhaps do a visual selection of the paragraph with vip and then comment with <C-/>
@danielebra brilliant, it works! thanks!
@danielebra Could you suggest a way of making this work on macOS, using <CMD-/> instead of <C-/>?
Currently <CMD-/> only comments the last line.
Thank you for any help!
@claudiodsf I was able to create a keybind like this for macOS in my VSCode keybindings.json:
{
"key": "cmd+/",
"command": "vscode-neovim.send",
"when": "editorTextFocus && neovim.init",
"args": "<C-/>"
},
For the benefit of anyone else coming to this issue, I finally figured the solution to another problem that was bothering me – the de-selection of the commented lines after toggling. The following restores the visual selection after <C-/>, which allows you to toggle on and off the selected lines without re-selecting them. This matches the behavior I was used to coming from VscodeVim.
.vimrc / init.vim:
if exists('g:vscode')
xmap <C-/> <Plug>VSCodeCommentarygv
nmap <C-/> <Plug>VSCodeCommentaryLinegv
endif
Based on this Stackoverflow it seems like there is a common practice to name <Plug> bindings with parentheses, which would make these binds slightly more clear to read, e.g.
xmap <C-/> <Plug>(VSCodeCommentary)gv
nmap <C-/> <Plug>(VSCodeCommentaryLine)gv
This would be a trivial change to vscode-code-actions.vim. if the maintainers are interested in supporting configuration like this I'd be happy to open a PR adding the parenthesized names while keeping the old ones for backwards compatibility.
Edit: actually I really only want this behavior in visual mode so I ended up with:
xmap <C-/> <Plug>VSCodeCommentarygv
nmap <C-/> <Plug>VSCodeCommentaryLine
@ian-h-chamberlain Your solution looks very interesting, but I am afraid I can't really follow what you are saying. There is a lot of info there and I don't see what the solution is vs additional info.
What is (VSCodeCommentary)gv and VSCodeCommentarygv?
Could you just write a simple step by step of what to do without any other commentary? Thanks!
@David-Else I don't fully understand <plug>, and I could be getting this wrong. Anyone is free to correct me, but I believe that it is used by vim plugins as a way of making a mapping that is easily overwriten. <plug> expressions are like functions that can only be called from a mapping.
(VSCodeCommentary)gv and VSCodeCommentarygv are the same, but the former is more readable than the latter because it makes it clear that only the VSCodeCommentary is part of the plug mapping.
gv simply tells vim to repeat the last visual selection. So if you select something, go back to normal mode, move around a little, and press gv, vim will re-select whatever you had selected before. (See :h gv.)
So what this mapping does is call VSCodeCommentary on the visual selection, and then re-select that visual selection. Without the gv, it would comment out the lines and go to normal mode.
Does that make sense now?
@pianocomposer321 Yes, the addition of gv as you point out, restores the selection as described by :h gv.
I am not fully confident in my understanding of <Plug> either but I _think_ that <Plug>(VSCodeCommentary) and <Plug>VSCodeCommentary are actually _different_ keybinds as far as vim is concerned. For example, if I add this to my .vimrc:
xmap <C-/> <Plug>(VSCodeCommentary)gv
I am no longer able to use <C-/> to toggle line comments. However, if I use:
xmap <C-/> <Plug>VSCodeCommentarygv
Then it works as I would expect. The parentheses are merely a convention that some plugin developers use to make keybindings more readable in user configurations. As an example see https://github.com/airblade/vim-gitgutter/commit/0469b8435ab8b2f25302ef04136591934730e56a in which they deprecate the non-parenthesized bindings in favor of the parenthetical ones.
I would suggest that the binding provided by vscode-neovim does something similar, which I would be willing to open a PR to implement.
@David-Else The simple answer is to add this to .vimrc or init.vim, whichever you have configured vscode-neovim to use:
if exists('g:vscode')
xmap <C-/> <Plug>VSCodeCommentarygv
nmap <C-/> <Plug>VSCodeCommentaryLine
endif
After which you will be able to use <C-/> to toggle line comments without losing your visual selection.
Is that helpful?
@ian-h-chamberlain
but I think that
(VSCodeCommentary) and VSCodeCommentary are actually different keybinds as far as vim is concerned.
Ahh, I thought when you said "it seems like there is a common practice to name
BTW, I meant to be replying to @David-Else, not you, I have edited my comment. Sorry for any confusion I may have caused. :-)
Most helpful comment
@claudiodsf I was able to create a keybind like this for macOS in my VSCode
keybindings.json:For the benefit of anyone else coming to this issue, I finally figured the solution to another problem that was bothering me – the de-selection of the commented lines after toggling. The following restores the visual selection after
<C-/>, which allows you to toggle on and off the selected lines without re-selecting them. This matches the behavior I was used to coming from VscodeVim..vimrc/init.vim:Based on this Stackoverflow it seems like there is a common practice to name
<Plug>bindings with parentheses, which would make these binds slightly more clear to read, e.g.This would be a trivial change to
vscode-code-actions.vim. if the maintainers are interested in supporting configuration like this I'd be happy to open a PR adding the parenthesized names while keeping the old ones for backwards compatibility.Edit: actually I really only want this behavior in visual mode so I ended up with: