Vimgrep mapping not working - vim

If I run manually the command
:vimgrep /\CTODO:\|FIXME:\|NOTE:/ %
everything works as expected. However when i try the following mapping:
nnoremap <leader>tl :vimgrep /\CTODO:\|FIXME:\|NOTE:/ %<CR>
I get the error:
E480: No match: \CTODO:|FIXME:|NOTE:
I don't why the map is not working.

| is used to separated vim commands. You have escaped the | to treat the pipe as one command however this changes regex into \CTODO:|FIXME:|NOTE: Look at the mapping via :nmap to see how the mapping has changed.
I suggest you use <bar> instead of the pipe symbol in your mapping:
nnoremap <leader>tl :vimgrep /\CTODO:\<bar>FIXME:\<bar>NOTE:/ %<CR>

Related

Use Multiple Patterns in Vimgrep in Key Mapping

In my vimrc I had a mapping to find all line with TODO in them and put them in the quickfix window:
nnoremap <leader>f :vimgrep /TODO/j % \| :cw<CR>
I now want to add the alternative pattern FIXME in the same way. So I tried
nnoremap <leader>f :vimgrep /TODO\|FIXME/j % \| :cw<CR>
and
nnoremap <leader>f :vimgrep /TODO<bar>FIXME/j % \| :cw<CR>
but neither return any results.
vimgrep /TODO|FIXME/j %
works at the : prompt when typed manually. So far my work-around is this:
function! FindFixme()
vimgrep /TODO\|FIXME/j %
cw
endfunction
nnoremap <leader>f :call FindFixme()<CR>
But I don't really understand why I can't get it to work as a single map command.
Thanks.
The regular expression item for alternation is \|, and you indeed need to escape a | so that it doesn't end the mapping command. Taken together, you need two backslashes: one for escaping and one to remain for the item:
nnoremap <leader>f :vimgrep /TODO\\|FIXME/j % \| :cw<CR>
But I would prefer the <Bar> notation, maybe even combined with <Bslash>:
nnoremap <leader>f :vimgrep /TODO<Bslash><Bar>FIXME/j % <Bar> :cw<CR>
You can further shorten this to:
nnoremap <leader>f :vimgrep /TODO<Bslash><Bar>FIXME/j %<Bar>cw<CR>

Error when loading .vimrc containing substitution

How do I map a substitution to a key in my .vimrc without getting an error when I source it?
I'm trying to add
nnoremap <leader>re :'<,'>s/<%=*\s//g | '<,'>s/\s-*%>//g
to my .vimrc but when I do so and reload the file I get the following error:
The problem is that you're combining two :s commands, but the command separator | concludes the :map command, so that the second substitution is executed immediately, causing the error. You need to escape the |, or better use the special <Bar> notation inside mappings:
nnoremap <leader>re :'<,'>s/<%=*\s//g <Bar> '<,'>s/\s-*%>//g
PS: Wouldn't it be more natural to define the mapping in visual mode (as it works on the last selection, anyway)? With a :vmap, the first '<,'> range will be inserted automatically:
xnoremap <leader>re :s/<%=*\s//g <Bar> '<,'>s/\s-*%>//g

what is the meaning of \ | in a map vim command?

Here is a map command.
nnoremap <F5> :w\|!R %<CR>
1.what is the meaning of \ here?
2. does | mean pipe ?
The | character separates two Ex commands, see :help :|. It's like ; in programming languages like C and Java. It has nothing to do with pipes; Vim hasn't that concept (which is typically found in shells).
It is escaped here so that the entire command sequence belongs to the mapping; i.e. it maps to :w|!R %<CR>. Without escaping, Vim would execute the following instead:
:nnoremap <F5> :w
:!R %<CR>
Note that you can also write <Bar> (cp. :help key-notation) instead of \|, and the former is more frequently used.

Vim map command to save file and run a test

How could I map a command to save the current file and then run it?
I am trying this:
:nnoremap <leader>r :w<CR>| !python %
This runs the python command instantly but not when I call the leader key. What am I missing here?
Just to follow up on what Conner was saying, you can do something like this:
nnoremap <leader>r :w \| !python %<cr>
Aha, I don't need the pipe character when writing a map, just a second colon:
:nnoremap <leader>r :w<CR> :!python % <CR>

I want to update the file (if necessary) and run the system command on current file

I realize that I can :nmap <leader>rc :!cat %<CR> to provide an easy set of triggers, but I would like to do this instead.
nmap <leader>rc :up :!cat %<CR> but it complains about needing only one filename. How do I get vim to recognize both commands, in series?
You are missing a <CR> after :up. <CR> tells vim you want a carriage return here.
nmap <leader>rc :up<CR> :!cat %<CR>
The reason up is complaining about multiple file names is that it sees :!cat and %<CR> as two arguments to up.
So the new macro executes
:up
:!cat %
instead of
:up :!cat %
(Side Note: you should probably use nnoremap instead of nmap)
ZyX recommends using the following mapping instead.
nnoremap ,rc :up\|execute "!cat" shellescape(#%, 1)<CR>
This uses | to separate commands and escapes the %. Escaping the % leads to a more robust mapping just incase the filename contains special characters.
Help for :h execute and :h shellescape

Resources