Nerdcommenter -- only comment out selected text - vim

In nerdcommenter for VIM, I can easy toggle a comment by doing:
[count]<leader>c<space> |NERDCommenterToggle|
Toggles the comment state of the selected line(s). If the topmost selected line is commented, all selected lines are uncommented and vice versa.
However, I find that I'll often way to only comment a visually-selected block of text, for example something like:
Is it possible to do this in nerdcommenter, or what might be a good way to do this in vim?

The problem is that :-commands can accept only line-range. That's in Vi/Vim design. A workaround is possible, but it could seem a bit complicated, as you can see from this question.
For this reason, I recently wrote a plugin vim-opera which implements such trick and also simplifies making mappings. For example, in my vimrc I have
nnoremap <expr><silent>gc opera#mapto('Comment!')
xnoremap <expr><silent>gc opera#mapto('Comment!')
nnoremap <silent>gcc :Comment!<CR>
Here :Comment is my own "commenter", but any line-range command will do.
The whole implementation takes more than 100 lines of code, so for those interested in details, I suggest to browse the source.

Related

Why can't I change a coc/neoclide key binding in Vim 8.1?

I love having a hotkey to format all of the code I'm using. I'd prefer having it on the lower case "f" button. I tried imitating the code given in the default config (the one which creates a new "Format" command) to bind it to "f", but it doesn't work.
Here's the relevant except from my .vimrc:
" Formatting selected code.
"original code commented out
"xmap <leader>f <Plug>(coc-format-selected)
"nmap <leader>f <Plug>(coc-format-selected)
"these bindings do not work
xmap <leader>f :call CocActionAsync('format')
nmap <leader>f :call CocActionAsync('format')
nnoremap <leader>f :call CocActionAsync('format')
"This does however work.... strangely:
" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocActionAsync('format')
As a side note, what counts as "selected" for neoclide? I tried using visual selection, but that doesn't seem to work.
Here's the link to the original config:
https://github.com/neoclide/coc.nvim#example-vim-configuration
Many thanks!
So the answer is actually quite simple. Two problems were being generated:
The first one comes from emulation, which basically disabled most of the useful function keys for vim, including CTRL, the START key and others... that made debugging unnecessarily hard. The second one was me confusing the keybinding syntax.
The only thing that seemed to work was to use the existing :Format command and apply it so shift-f:
nmap F :Format<CR>
That's all. I can't imagine that this solution would've taken more than .01% brainpower of anyone experienced with the software. My initial attempts at fixing the problem failed due to the aforementioned emulation problems - I had posted the original not working code in order not to make things too confusing.
Even though the problem is solved now, there is a certain bitterness remaining. Assuming people aren't using software "properly" just because they are learning or do not have your proficiency level seems a very inadequate thing to do. I'd bet that most programmers started by learning from small examples instead of reading a 2000-page documentation first. If you don't want to help, remain silent. I always try to help with what little knowledge I have in, say, C# or TS, or Latin, Spanish or Czech for that matter. Have a good night.

Vim place comment uncomment in very beginning of line shortcut

I know how to comment a line in vim by doing Shift-I-//. This ends up in something like:
//int a = 1;
Instead, I would like to put comment in the very beginning of line, like:
// int a = 1;
Currently I can do this by 0-i-//.
May I ask for a shortcut like i.e. Shift-0-// (or even shorter)?
I installed nerdcommenter, tried all the default maps and none does that?
I did:
let g:NERDDefaultAlign = 'left'
And its not bad, but I still would like to have the comments on the very beginning of the line.
Why not pick a popular comment plugin? I use nerdcommenter, and I am satisfied with it.
If you want to do the comment/uncomment toggle on your own, you may want to know gI. Like:
nnoremap whatever gI//<esc>
I still recommend the plugin, because even if build your own function check if there is // on BOL, to toggle comment, it adds/removes only //. If you opened a python file, or shell script or vimscript, you cannot use this mapping any longer. The plugin checked the filetype, it is convenient. Well you can of course write all things by yourself, to reinvent the wheel.
put this in your vimrc
nnoremap <leader>/ 0i//<esc>
Now every time you press <leader>/ you will comment the line the way you want.
(If you don't have a <leader> yet, look up :h leader and carry on from there).

VIM keybinding to jump back to initial position after indenting the whole file

I have created a keybinding that should indent a whole file.
My first solution looked like this:
map <F4> gg=G
The problem is that after pressing F4, the cursor jumped to the first line of the file. So I have tried to improve my solution with the feature of markers, look like this:
map <F4> mzgg=G'z<CR>
I expected this would have resolved my problem, but the command do the same as the first. When I try to jump to the z marker manually vim told me "marker not set".
After changing the keybinding, I have or course restarted vim! I am using the GVIM 7.3 on a WIN 7 machine.
Thank you in advance for your Help!
Edit:
After trying to get my keybinding working by tipping it directly to vim commandline. I find out that the keybinding was working quite nice. I think problem is that I create a session some times ago (with mksession) and if you load a session I think vim ignores the vimrc-file. Is this assumption right?
Solution:
In these thread I find a soultion to make mksession save less options.
Another lightweight approach: set the ` mark, format the buffer and jump back to the mark afterwards.
:nnoremap <key> m`gg=G``
I would recommend the use of CTRLo and CTRLi which allow to go respectively backward and forward in the jump list. See :help jumps.
The following mapping
map <F4> gg=G2<C-o>
works. (It jumps back two times in the jump list)
But generally, the jump list is a great way to navigate in a file, this is likely the shortcuts that use the most in my daily use. It is also works if you jump to a tag to go back to your original location.
You might also want to use nnoremap rather than map, this way it will only work in normal mode, and you could potentially reuse F4 in combination in another key binding without having recursive mappings.
so
nnoremap <F4> gg=G2<C-o>

vim: Check if a line is wrapped in a comment (/* */) and toggle it on and off

Just asked a question a few moments ago about how to wrap a line in a comment which yielded this fantastic snippet:
nnoremap - mzI/* <esc>A */<esc>`z
I wanted to open another thread to ask how I can turn this into a toggle. Meaning it first checks if the line is wrapped in /* */ and removes the comment or adds it if it is not there.
Does this have to be a script or can I do this with a map? Also I don't want to use a plugin for this because its simple and I would like to see how its done.
Here you go:
nnoremap <expr> - getline('.') =~ '^\s*/\*.\+\*/$' ? '^3x$daw' : "I/* \<esc>A */\<esc>"
The un-commenting is done by ^3x$daw which deletes the beginning and ending portions of the mapping. The detection is done via a regex on the current line, getline('.'). I have removed the z mark from the comment portion of the mapping as it does a poor job of keeping cursor in the "same" spot.
This is a great example of a fancier mapping. However there are somethings to think about:
This mapping pollutes the . and " registers.
Only works on filetypes with c-style comments
No visual or operator like mappings, meaning you can not mass toggle.
Does not repeat via .
I highly recommend a comment plugin. I currently use Tim Pope's vim-commentary plugin.
For more help see:
:h :map-<expr>
:h getline(
RE I don't want to use a plugin for this because its simple.
It's only simple until you use this heavily; Peter Rincker's answer already lists some issues. As you probably rely on (un-)commenting a lot, this is really a good indication for a robust, proven plugin.
Let me throw in a recommendation for The NERD Commenter; it has the toggle mapping you're asking for, and supports several languages. Apart from commentary, also have a look at tComment.

Insert character without entering insert mode?

Sometimes I want to insert a # to comment out a line and test it quickly. Currently I do:
i#ESC:w
Is there something shorter I can do?
Although I agree with others that there are better ways to comment and uncomment code, it seems that people have gotten distracted and forgotten to actually answer the question.
This is my approach to inserting a single character:
:noremap <key> i <Esc>r
I tend to find that I need to replace, remove, or add single characters very often if I'm correcting typos, so (resp.) r, x, and whatever is chosen for <key> in the above become very handy.
Note that . is also particularly handy for this sort of task. It repeats the previous action.
Personally though, I only map this function to a valuable key when I'm doing a task where I use it frequently enough to justify occupying a prime spot on the keyboard (such as correcting typos), because really, it only saves one keystroke per use and that's only when <key> is not a combination, which of course limits availability.
I map a couple of things to my <leader> key (\ by default):
" # comment the current line
nnoremap <leader>d I#<ESC>
" block comment in visual mode
vnoremap <leader>c <ESC>'<O/*<ESC>'>o*/<ESC>V'<k
If you want to add a # to the start of a group of lines, then do this:
<ctl-v>
j (as many times as necessary
I#
<esc>
You could use a recording. From normal mode, type:
qlml0i#<press escape>`lq
Then to comment out a line, just press #l
Mapping in vim is so easy that I might do something like
:nmap CC I#<Esc>:w<CR>
on the fly. If I get used to it, then I will add it to my vimrc file.
:help key-mapping
:help usr_40.txt
Actually there is a plugin you might wanna take a look at:
http://www.vim.org/scripts/script.php?script_id=1218
It is specifically designed for that purpose.
I'm particularly fond of the tComment plugin. gcc to comment a line, repeat to uncomment, multiple lines, motions, etc.

Resources