How can you map a binding with a pipe? - vim

e.g. I want to map
nnoremap <a-v> :vs | term<cr>
but vim is interpreting this as nnoremap <a-v> :vs followed by the separate command term<cr>. How do I declare the the associativity here? Using eval and execute do not work.

I asked too soon, figured it out a minute later: you simply escape the pipe:
nnoremap <a-v> :vs \| term<CR>

Related

How to map a key in a command line argument inside a key mapping?

The naive approach
nnoremap <leader>s :!echo "foo" <bar> vim -c="nnoremap x :q<cr>" -<cr>
displays errors. Is there a way to achieve this?
Figured it out. There are two problems with my original code. The first being an equals sign after -c. For the other, the solution is to use <lt>cr> instead of <cr>. So the entire command would look like this:
nnoremap <leader>s :!echo "foo" <bar> vim -c "nnoremap x :q<lt>cr>" -<cr>
:help <lt>

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.

How to escape "<CR>" in a mapping in vimscript

I want to construct a command line within a mapping, using the :execute normal "commandstring" techinique. But I can't do it from within a mapping as vim immediately interprets the "" as a keypress. So this doesn't work:
nnoremap <leader>jj :execute "normal :tabnew foo.txt\<cr>"<cr>
I tried doubly escaping the backslash, to no effect:
nnoremap <leader>jj :execute "normal :tabnew foo.txt\\<cr>"<cr>
Now vim types in the backslash and then interprets the as a keypress.
Any way out of this?
That's indeed tricky. You have to escape the < character as <lt>, so that the <cr> is not parsed as special key notation:
nnoremap <leader>jj :execute "normal :tabnew foo.txt\<lt>cr>"<cr>
Note that your example doesn't need any of this; :normal :...<CR> is the same as ...
nnoremap <leader>jj :tabnew foo.txt<cr>

Vimgrep mapping not working

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>

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