Reputation: 617
I try to comment and uncomment css file with vmap
when I select lines in css file and comment them out with 'xx'
autocmd BufEnter *.css vmap xx :s/\%V\s*\(\S.*$\)\%V/\/* \1 *\//g <CR>
It works perfectly
But when I try to vmap 'xu' to uncomment the css code,
autocmd BufEnter *.css vmap xu :s/\%V\/\*\|**\/\%V//g <CR>
'xx' comment => background-color => /* background-color:red; */
'xu' uncomment => /* background-color */ => background-color
The mapping is try to remove '/*' and '*/'
from my selected lines in css file.
I got following error:
E871: (NFA regexp) Can't have a multi follow a multi !
E61: Nested *
E476: Invalid command
It seems to me I CAN NOT have 'or' operator between '\%V and \%V' which is visual block in Vim.
Anyone know how to solve the problem
Upvotes: 1
Views: 193
Reputation: 172638
If you check your mapping, you'll see that it's not defined as expected:
:vmap xu
v xu :s/\%V\/\*|**\/\%V//g <CR>
Inside a mapping, the |
command separator would end the mapping command, and therefore needs to be escaped. (Cp. :help map-bar
). This usually is done via <Bar>
, but can also be done by prepending a \
. Accidentally, your regular expression had just this, thereby avoided the mapping definition error, but also corrupted the mapping.
vmap xu :s/\%V\/\*\<Bar>**\/\%V//g <CR>
You probably should also consistently escape the second literal *
; this would have given you a different (pattern not found) error instead of the E871:
vmap xu :s/\%V\/\*\<Bar>\**\/\%V//g <CR>
... works, but isn't how it's usually done. Vim has filetype detection, and out of the box detects *.css
as filetype=css
for you. There's no need to duplicate that information into your autocmd. Instead, you can hook into the FileType
event:
autocmd FileType css vmap xu :s/\%V\/\*\<Bar>\**\/\%V//g <CR>
I would recommend putting any settings, mappings, and filetype-specific autocmds into ~/.vim/ftplugin/{filetype}_whatever.vim
(or {filetype}/whatever.vim
; cp. :help ftplugin-name
) instead of defining lots of :autocmd FileType {filetype}
; it's cleaner and scales better; requires that you have :filetype plugin on
, though. Settings that override stuff in default filetype plugins should go into ~/.vim/after/ftplugin/{filetype}.vim
instead.
:vnoremap
instead of :vmap
; it makes the mapping immune to remapping and recursion.<buffer>
argument to limit it to the (CSS) buffer.:substitute
; it avoids the escaping of the /
in the pattern and makes this a bit more readable.I would put the following into ~/.vim/ftplugin/css_mappings.vim
:
vnoremap <buffer> xu :s#\%V/\*\<Bar>\**/\%V##g <CR>
(Unless you're a minimalist that avoids plugins at some cost, or if you've done this only for the learning experience.)
Please note that there are several commenter plugins that do this very well, and those are generic (and often extensible) so that they work for any filetype:
Upvotes: 2