Mapping a working substitute command to a shortcut via vimrc - vim

The following substitute command works fine on the command line:
:s/\vlabel\{(\w|:)+}/nonumber
It searches for label{eq:xyz123} and replaces its occurence on the current line line with nonumber.
I would like to map this to a command via vimrc. I tried:
nnoremap <leader>nn :s/\vlabel\{(\w|:)+}/nonumber<CR>
but this gives the error:
E492: Not an editor command: :)+}/nonumber<CR>
What is the right way to effect this mapping?

You can use:
nnoremap <leader>nn :s/\vlabel\{(\w<bar>:)+}/nonumber<CR>
Note the use of <bar> instead of |. The error occurs because | is interpreted as a delimiter of commands; i.e., Vim is interpreting your command as if there were two separate lines:
nnoremap <leader>nn :s/\vlabel\{(\w
:)+}/nonumber<CR>
For more, you can read :help map-bar.

Related

Regex in .vimrc throwing "Not an editor command"

I am trying to create a keybinding to delete all the commented lines in the file.
The following gives me the desirable result :g/^\(#\|$\)/d
I am declaring the binding as following in ~/.vimrc
nnoremap <leader>dcl :g/\v^(#|$)/d<cr>
It is throwing the following error:
E492: Not an editor command: $)/d<cr>
What is the proper way to declare a keybinding with regex?
Replace your binding by:
nnoremap <leader>dcl :g/\v^(#<bar>$)/d<cr>
Indeed, in scripts or in the command line, vim considers | characters as a command delimiter; so you have to replace it by <bar>.

How to paste the Yanked lines in vim command line after typing other command?

I wanted to paste the yanked line in the vim command prompt after typing certain command.
I saw a solution where they asked to enter <Ctrl-R><Shift-"> to paste the yanked lines in the vim command prompt, however I am having the following problems:
When I try like, :tabnew and then type <Ctrl-R><Shift-">, whatever yanked line gets pasted after :tabnew line.
Eg: :tabnew /disk/bin/hello.log
The above solution doesn't work if I map the same above command in the vimrc. I tried adding the following map in my .vimrc:
:map <S-P> :<C-R><S-">
When I try :tabnew and type <S-P>, it is not pasting the yanked line, i.e. the mapped command is not working.
Can anyone help me on the above scenario?
FOLLOW-UP QUERY:
Is it possible to mix normal mode and command line mode operations?
For Eg:
a. I have a line in text file which is a directory path and wanted to open that directory in vim.
b. Instead of doing Yanking [S-Y] the line and then doing mapped command [map <C-T><C-O> :tabnew <C-R><S-"><bs><CR>] to open the directory for vim, is it possible to do something as given below ?
nnoremap <F7> <S-Y>cnoremap:tabnew <C-R><S-"><bs><CR>
Please drop you comments/suggestions?
The : command line prompt is "Command-line-mode" (see :h Command-line-mode, :h cmdline, or :h : [all show the same help]). You can map keys in that mode using :cnoremap. So you seem to be looking for this:
:cnoremap <s-p> <c-r>"<bs>
The backspace at the end removes the trailing end-of-line character that is (probably) at the end of the buffer.
I very strongly suggest you use a different mapping than <s-p>, because that will be triggered every time you try to type a capital "P".

Why does the <C-n> syntax for using control key work with :command command but not with :normal command?

I am trying to execute a normal mode command Ctrl-n or j from Ex mode. Normally, one would do this using the :normal command. For example, the following command moves the cursor one line down.
:normal j
So does the following command. Note: ^N is typed by pressing Ctrl-v Ctrl-n.
:normal ^N
But the following command does not work. This command seems to have no effect on the buffer.
:normal <C-n>
However, when I create a new Ex command for Ctrl-n using the following command, it works!
:command Down <C-n>
Even this works, although normal is redundant here.
:command Down normal <C-n>
Now, I can use the Ex command :Down to move the cursor one line down.
My question is why does the <C-n> syntax not work with the :normal command but works with the :command command?
use :exec and escape the <c-x>:
for example:
:exec "normal \<c-n>"
in fact the instruction you can find in :h :normal help doc:
to use |:execute|, which uses an
expression as argument. This allows the use of
printable characters to represent special characters.
Example: >
:exe "normal \<c-w>\<c-w>"
Your question is probably academic (or you are trying to solve another problem) but, for what it's worth, you can already do :+ and :join.

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

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