Remap Ctrl-D in vim - vim

I want to remap another key combo, say CTRL-G, to function as CTRL-D does (note: not the same as S-Down/PageDown/CTRL-F).
What I have so far is:
nmap ^G :exe 'normal '.&scroll.'^E<CR>'
Bringing up my vim command mode and typing this in, it works perfectly. However, when I save my .vimrc and reload vim, I get the following error when pushing CTRL-G:
E114: Missing quote: '
E15: Invalid expression: 'normal '.&scroll.'
It seems to be stuck at not evaluating the ^E appropriately. However, I have been entirely unsuccessful in using or any other way of specifying CTRL-E. What am I missing here?

^G and ^E are special characters, and do not work well when you put them in the .vimrc. You need to use <C-g> and <C-e>, but since your Ctrl+E is placed inside a string, you need to escape it and write \<C-e>. You also need to use double quotes instead of single quotes - otherwise you can't do the escaping.
In other note - you should probably use nnoremap instead of nmap, so that if you remap <C-e> somewhere else, <C-g> will still behave like the original <C-e>.

I think you can just write <C-E> for CTRL-E.

Related

Some key mappings for combinations with the PageUp/PageDown keys don't work

I use rxvt-unicode terminal emulator on Manjaro, and the following two mappings in my .vimrc don't work,
nnoremap <C-PageUp> :tabprevious<CR>
nnoremap <C-PageDown> :tabnext<CR>
even though the following does work
nnoremap <C-t> :tabnew<CR>
I think the reason for the behavior you observe is exactly the one described here.
In other words, something like this (what the rhs is doesn't matter)
nnoremap <C-PageUp> :echo "hello"<CR>
will not work as Vim does not now which escape sequence corresponds to the keycode <C-PageUp>.
Therefore, you can provide it with the escape sequence corresponding to Ctrl-PageUp, as in
nnoremap ^[[5^ :echo "hello"<CR>
where the first two characters of the escape sequence, ^[, are part of a single unit that corresponds to Escape (that's why escape seqeunce).
You can get the whole sequence (which could be different from mine in your terminal, by the way) from insert mode by hitting
Ctrl+VCtrl+PageUp; however, given the meaning of ^[, you can also use Ctrl+VEscape and then type [5^ manually.
Unfortunately, putting set <C-PageUp>=^[[5^ causes error E518. I don't know why.
On the other hand, another solution is the following (again described here)
set <F37>=^[[5^
nnoremap <F37> :echo "ciao"<CR>
where <F37> is one of the extra function keycode Vim provides. I have no clue where this thing is in the :help.

Unusual behavior with or operator in vimrc

I usually do a search and replace in vim that looks like this:
:%s/\([\.!?]\|[\.!?]"\)\s\s/\1text /g
So it looks for either a period, exclamation point, question mark, or any of the above followed by a quote and two spaces. It works fine.
But when I map this in my vimrc like so
map <F4> :%s/\([\.!?]\|[\.!?]"\)\s\s/\1text /g<CR>
and then press F4 I get this error message:
E486: Pattern not found: \([\.!?]|[\.!?]"\)\s\s
It is removing the backslash before the pipe for some reason and I have no idea why. Does anyone know how to correct this behavior?
In a :mapping, the pipe character is special. Use <Bar> instead:
:noremap <F4> :%s/\([\.!?]\<Bar>[\.!?]"\)\s\s/\1text /g<CR>
Also, you should use :noremap; it makes the mapping immune to remapping and recursion.

Mapping a key in VIM

I've tried:
:map <F2> :.y" :g/<C-R>"/d<CR>
No luck :(
What this does, yank the current line into register "
Then, globally, delete lines that match exactly the line in the register.
It works dandy when I do it manually.
:vmap <F2> ["]yy<ESC><ESC> :g/<C-R>"/d<CR>
Similar to above - I select a few words, whatever - I make a selection, then yank it to register ". I then globally, delete the lines that match whats in the register.
It works dandy when I do it manually.
What am I doing wrong?
You might try this for the first one:
:nnorempa <F2> :silent exe "g/".getline(".")."/d"<CR>
For the second, something like this if you want to delete only the words:
:vmap <F7> y:silent exe "%s/".#"."//g"<CR>
And this if you want to delete the matching lines:
:vmap <F7> y:silent exe "g/".#"."/d"<CR>
You have remapped F2 to :.y" :etc. You need <cr> not a simple space. If you type :.y" in vim and don't hit ENTER but space, nothing will happen.
So:
:nnoremap <f2> :.y"<CR>:g/<C-R>"/d<CR>
could do it.
Still, warning, if your line contains any of /\*[~$^. this could fail. You could use the expression register in order to escape in-place:
:nnoremap <f2> :.y"<CR>:g/<c-r>=escape(#", '/\*[~$^.')<cr>/d<cr>
Still better, without overwriting your default (") register is:
:nnoremap <f2> :g/^<c-r><c-o>=escape(getline('.'), '/\*[~$^.')<CR>$/d<cr>
which will delete all identical lines. Still note that 'ignorecase' or 'smartcase' matter.
First of all - make sure you're using vim :)
vim --version
Here's the mapping I was going for. As I go through lots of data in log files, this will be incredibly useful. Select the area you want to eliminate, then and all instances of highlight area is done for.
NOTE: This does NOT go through the highlighted text and escape any regex characters. So a /, *, ^ will foul it up.
:map <F2> y:g/<C-R>"/d<CR>
:)

Vim Pre-Exit (Esc Key) Command?

Right now in Vim when I go to a new line (or press 'p' or 'o' in normal mode) I get a lovely automatic indent, that also disappears if I exit insert mode without adding anything to it.
Is there a way to bind something to before I exit insert mode, such as inserting a phantom character then removing it?
Argh, I just read about this exact thing like two days ago but I can't remember where.
Anyway, the trick is to input a character right after <CR> and delete it immediately. There are a bunch of ways to do it:
<CR>a<Esc>x
<CR>a<C-w>
<CR>a<BS>
--EDIT--
Vim being Vim there are probably many other ways.
To automate these, you need to add a mapping to your .vimrc:
inoremap <CR> <CR>a<BS> " insert mode mapping for <CR>
nnoremap o oa<BS> " normal mode mapping for o
But I'm not sure you should overwrite defaults like that.
--EDIT--
However, what is annoying with Vim's default behaviour is that you may need to do some <Tab><Tab><Tab><Tab> before actually inputing some text on non-indented line or do == when you are done or rely on the automatic indentation rules for your language at the next <CR>.
All that can be skipped by using <S-S> which puts you in INSERT mode right at the correct indentation level.
Try either cc or S in normal mode to change a line with respect to indention. No need for phantom characters.
:h cc
:h S
A mapping like the following should do the trick:
imap <esc> <esc>:s/\s\+$//<CR>
This one deletes trailing characters when you press esc in insert mode.

Mapping :nohlsearch to escape key

I like to use hlsearch but I hate to keep everything highlighted after searching, to solve this problem I could simply use :nohlsearch or an abbreviation of it but that is still to much effort so I decided to try to do that on pressing escape. What I came up with is:
nnoremap <ESC> :nohlsearch<CR>
This works exactly as I want it to in GVim which I usually use for development but it does not work in vim.
If I search something in vim, press escape to deactivate the highlighting and use one of the arrow keys to navigate vim goes directly into insert mode and inserts a character on a new line.
As I never really came around to using h, j, k and l for navigation this is really annoying and I would like to know how I can make vim behave like gvim.
If you need more information you can find my entire vim configuration here.
Your problem is that when you press <Up> terminal sends something like <Esc>OA (you will see it if you type <C-v><Up> in insert mode) which is remapped to :nohlsearch<CR>OA. I do not know any solution except not mapping a single <Esc>, try either mapping to double <Esc>.
I created this map to disable search when press double <Esc>
nnoremap <silent> <Esc><Esc> :let #/ = ""<CR>
is :noh still too much work?
EDIT: I don't know about you, but I personally think :noh is easier than pressing Esc key, since I can press all the buttons without stretching my pinky too far (which is why I think the default mapping of Esc for going back to Command Mode from Insert Mode is a bit unfortunate). If you really use the :nohlsearch that much, you probably should remap it to something you can reach from the Home Area (i.e. regular letters, or numbers, or perhaps Ctrl-letters).
Anyway, typing the exact command you give works in my vim (on gnome-terminal). Are you sure you put the rule in .vimrc file, instead of .gvimrc? No luck after restarting vim? Try :source /path/to/config/file and see if that makes it to work.

Resources