Mapping Alt+n to pagedown in vim - vim

I want to map the Alt+n key combination in insert and escape mode to pagedown (moving down by large amount of lines) .
I have tried adding following lines to .vimrc file but not working.
:map <M-n> <PageDown>
:map <A-n> <PageDown>
:imap <M-n> <PageDown>
:noremap <A-n> <PageDown>
Is there some way I can map Alt+(some alphabet) (not a system key binding) to other key in vim ?

I found the solution afterwards at https://vi.stackexchange.com/questions/2350/how-to-map-alt-key .
When Alt+alphabet is pressed, characters sent by the keyboard are ^[+key , so we first map the Alt+key to it's corresponding equivalent and then use noremap.
For example to map Alt+n to pagedown, this will word
execute "set <M-n>=\en"
nnoremap <M-n> <PageDown>

Related

What the D-S-Up means in vim?

I find a .vimrc file config:
" Move selection up/down (add =gv to reindent after move)
:vmap <D-S-Up> :m-2<CR>gv
:vmap <D-S-Down> :m'>+<CR>gv
I know the D-S-Up must be a key, but what is the key?
I type:
:help D-S-Up
nothing happened
:help key-notation tells you the meaning of all those <key> notations.
You can't expect :help D-S-Up to do anything because:
it doesn't follow established patterns like i_ctrl-r,
it is a custom mapping and Vim only provides documentation for its own commands.
<D> is the Cmd key on Mac keyboards, <S> is the Shift key, and <Up> is the Up arrow key.
So <D-S-Up> means Cmd + Shift + Up.
The Cmd key only works in the MacVim GUI.
Non-portable mappings are worthless.
One should use :xmap or :xnoremap for visual mode mappings, not :v*.
Non-recursive mappings should be used by default unless one really wants recursion.
Using someone else's vimrc is a bad idea.
By the way, here are enhanced versions of those mappings:
nnoremap <silent> <D-S-Up> :<C-u>move-2<CR>==
nnoremap <silent> <D-S-Down> :<C-u>move+<CR>==
xnoremap <silent> <D-S-Up> :move-2<CR>gv=gv
xnoremap <silent> <D-S-Down> :move'>+<CR>gv=gv
where:
<silent> prevents the commands in the mapping from echoing useless info,
<C-u> removes any default range inserted by Vim,
move-2<CR> is a more readable version of m-2<CR>,
== re-indents the line,
gv=gv reselects the lines, re-indents them, and re-selects them again.
Have a look at Move entire line up and down in Vim
In an answer you can read (concerning the line :vmap <D-S-Up> :m-2<CR>gv):
According to the shortcuts above, pressing Cmd-Shift-Up/Down will shift the block selection up/down. "D" is the Command key in MacVim, for Windows try "C" (Control), or "A" (Alt) (eg. would be Control Alt f).
Since I don't have a Mac myself, I can't check, but it's most certainly true.

How to remap Vim keys (PageUp and PageDown)

I want to remap <PageUp> to <C-u> and PageDown to <C-d> per the Vim scrolling documentation.
As it stands right now, my /etc/vim/vimrc looks like this:
nnoremap <PageUp> <C-u>
nnoremap <PageDown> <C-d>
I've tried a lot of different combinations and nothing I've done has worked.
My goal is to make the cursor move to the Start Of File or EOF when holding down PageUp/PageDown. As it is right now, the cursor stops before it gets all the way to the top (and PageDown scrolls past the EOF). Just annoyances I'm trying to fix.
EDIT: The above settings work fine. I was placing my mappings too early in the file.
What about the following mappings?
nnoremap <PageUp> gg
nnoremap <PageDown> G
Or simply using gg and G?
Instead of placing the mappings into the system-wide /etc/vim/vimrc, you should put user customizations into the ~/.vimrc file. Nonetheless, the global configuration (if that's what you want) should work, too. That it doesn't means that the mappings get cleared or redefined. You can check with
:verbose nmap <PageDown>
If it didn't get redefined, you have to hunt for :nunmap commands in all loaded scripts (:scriptnames), or capture a log with vim -V20vimlog.
You can do this with
map <silent> <PageUp> 1000<C-U>
map <silent> <PageDown> 1000<C-D>
imap <silent> <PageUp> <C-O>1000<C-U>
imap <silent> <PageDown> <C-O>1000<C-D>
from fixing-pageup-and-pagedown

How to map <c-leader> in vim?

I would like to map ctrl+leader key. Is it possible?
Tried: :nnoremap <c-leader> :CtrlP<CR>
And it does not work.
(ctrlp bindings conflict with yankring bindings)
<Leader> is a special key notation in Vim; as such, it cannot be combined with modifiers such as C-. Assuming the default setting for it (i.e. \), you can use this:
nnoremap <c-\> :CtrlP<CR>
There are two issues, here:
You didn't read CtrlP's documentation where you would have found this:
Use this option to change the mapping to invoke CtrlP in Normal mode:
let g:ctrlp_map = '<c-p>'
<leader> is supposed to be a cross-platform alternative to using the common modifier keys (Alt, Ctrl, Shift, Cmd) in mappings.
Normally, you would use <leader> in place of <Ctrl> as in:
nnoremap <leader>p :CtrlP<CR>
This line in your ~/.vimrc will probably solve your problem:
let g:crtlp_map='<F11>'
Though it won't help much here are my mappings for CtrlP:
nnoremap <leader>f :CtrlP<CR>
nnoremap <leader>b :CtrlPBuffer<CR>
nnoremap <leader>m :CtrlPMRUFiles<CR>
nnoremap <leader>t :CtrlPTag<CR>
For example to map leader key to space try this ...
let mapleader=" "

Mapping <Shift>-Arrows to selecting characters/lines

I started to use vim recently, but I miss the character/line selection methods from other text editors. By default vim maps <S-Up>, <S-Down> to jumping one page up/down and I want to remap these to text selection.
Is there a way to do that?
I completed #escrafford mapping with insert mode's ones:
" shift+arrow selection
nmap <S-Up> v<Up>
nmap <S-Down> v<Down>
nmap <S-Left> v<Left>
nmap <S-Right> v<Right>
vmap <S-Up> <Up>
vmap <S-Down> <Down>
vmap <S-Left> <Left>
vmap <S-Right> <Right>
imap <S-Up> <Esc>v<Up>
imap <S-Down> <Esc>v<Down>
imap <S-Left> <Esc>v<Left>
imap <S-Right> <Esc>v<Right>
Also mapping usual copy/cut/paste like this you can return to insert mode after select+copy, for example.
vmap <C-c> y<Esc>i
vmap <C-x> d<Esc>i
map <C-v> pi
imap <C-v> <Esc>pi
imap <C-z> <Esc>ui
Now you can start a shift+arrow selection from any mode, then C-c to copy, and then C-v to paste. You always end in insert mode, so you have also C-z to undo.
I think this approaches more to the 'expected standard' behaviour for a text editor yu are asking for.
There's an specific option for this: keymodel:
'keymodel' 'km' string (default "")
global
{not in Vi}
List of comma separated words, which enable special things that keys
can do. These values can be used:
startsel Using a shifted special key starts selection (either
Select mode or Visual mode, depending on "key" being
present in 'selectmode').
stopsel Using a not-shifted special key stops selection.
Special keys in this context are the cursor keys, <End>, <Home>,
<PageUp> and <PageDown>.
The 'keymodel' option is set by the |:behave| command.
TL;DR: To enable the behavior you want, use:
set keymodel=startsel
If you also want to leave visual mode when using <Up> or <Down> without <Shift> pressed, you can use:
set keymodel=startsel,stopsel
Slightly different from progo's answer - this gives the same feel as mac apps normally have:
nmap <S-Up> v<Up>
nmap <S-Down> v<Down>
nmap <S-Left> v<Left>
nmap <S-Right> v<Right>
vmap <S-Up> <Up>
vmap <S-Down> <Down>
vmap <S-Left> <Left>
vmap <S-Right> <Right>
The differences being switch to visual mode instead of visual line mode, and not losing the initial up/down etc keystroke.
Vim doesn't bend to that easily in my opinion. The terminal one doesn't even recognize Shift-Up in my case! I thought the v (character-wise selection) or V (line-wise selection) was among the easier concepts to learn about vi/vim.
If this works (can't test right now), this is something you'll want:
" activate visual mode in normal mode
nmap <S-Up> V
nmap <S-Down> V
" these are mapped in visual mode
vmap <S-Up> k
vmap <S-Down> j
"
" etc...
" similarly <S-Left>, <S-Right> for v
I found another solution that is easier to execute. The command ':behave mswin' does all that is needed to use shift plus cursor keys to select text. Works from any mode. It also supports Cmd-c, Cmd-v and Cmd-x. It works in MacVim but I did not try other platforms.
It is definitely recommended that you don't remap this feature. Simply switching to visual mode and using v and the arrow keys is a better idea. V will select the entire line, v$ will select to the end of the line and vw will select the next word. There are many more commands you can use to select different lines and words. Learning these commands will not only be useful for selecting but also useful for editing your files more efficiently.
This mapping keeps insert mode during selection (visual mode) and it starts on the correct position. You can also select a word to the left or right using Ctrl-Shift-Left/Right (if your terminal supports it):
" Select with shift + arrows
inoremap <S-Left> <Left><C-o>v
inoremap <S-Right> <C-o>v
inoremap <S-Up> <Left><C-o>v<Up><Right>
inoremap <S-Down> <C-o>v<Down><Left>
imap <C-S-Left> <S-Left><C-Left>
imap <C-S-Right> <S-Right><C-Right>
vnoremap <S-Left> <Left>
vnoremap <S-Right> <Right>
vnoremap <S-Up> <Up>
vnoremap <S-Down> <Down>
" Auto unselect when not holding shift
vmap <Left> <Esc>
vmap <Right> <Esc><Right>
vmap <Up> <Esc><Up>
vmap <Down> <Esc><Down>
This may be useful for quickly selecting small parts when you're in insert mode but I recommend using the default commands for selecting larger parts.
I've written this to be able to navigate using Alt+hjkl (and friends) and select using Alt+HJLK when both in insert, visual and normal mode.
So the same can be applied to normal arrow keys as well
let hjklfriends = ['h','j','k','l','w','e','b','W','E','B', 'n', 'N', 'y', 'Y', 'p', 'P']
" define if using alt (it works in neovim) or Escape key.
function! Meta(key)
if has('nvim')
return "<A-" . a:key . ">"
else
return "<Esc>" . a:key
endif
endfunction
execute 'noremap! ' . Meta('h') . ' <left>'
execute 'noremap! ' . Meta('j') . ' <down>'
execute 'noremap! ' . Meta('k') . ' <up>'
execute 'noremap! ' . Meta('l') . ' <right>'
execute 'noremap! ' . Meta('b') . ' <C-Left>'
execute 'noremap! ' . Meta('w') . ' <C-Right>'
execute 'noremap! ' . Meta('e') . ' <C-Right>'
for k in hjklfriends
execute 'imap ' . Meta(k) . ' <C-o>' . k
if k =~ '[a-z]'
execute 'imap ' . Meta(toupper(k)) . ' <C-o>v' . k
execute 'vmap ' . Meta(toupper(k)) . ' ' . k
execute 'nmap ' . Meta(toupper(k)) . ' v' . k
endif
endfor
Modified from #RubenCaro's answer.
The issue is: when escaping from insert mode, the cursor will be shifted to the left by one. This makes the behaviour of the keys , , and in insert mode different from the behaviour of other generic text editors.
Assuming that the goal is to make those keys behave like generic editor, the mapping should be slightly modified to:
" shift+arrow selection
nmap <S-Up> v<Up>
nmap <S-Down> v<Down>
nmap <S-Left> v<Left>
nmap <S-Right> v<Right>
vmap <S-Up> <Up>
vmap <S-Down> <Down>
vmap <S-Left> <Left>
vmap <S-Right> <Right>
imap <S-Up> <Esc>v<Up>
imap <S-Down> <Esc>vlvv<Down>
imap <S-Left> <Esc>v<Left>
imap <S-Right> <Esc>vlvv<Right>
vmap <C-c> y<Esc>i
vmap <C-x> d<Esc>i
map <C-v> pi
imap <C-v> <Esc>pli
imap <C-z> <Esc>ui

Navigating in Vim's Command Mode

I am a long time emacs user learning Vim. Emacs lets me navigate in the mini-buffer (where I issue commands like C-x C-s) using the same navigation keyboard shortcuts as in any other buffer. For example, I can navigate forward one character using C-f, even while in the mini-buffer. I could also use the arrow keys, but they are too far away.
Is there any keyboard shortcut to navigate in Vim's command mode (:), without using the arrow keys -- equivalent to emacs C-f, C-b? Thanks.
Adding to Greg Hewgill's answer, you can use q: to open the command-line window, where you have any Vim editing power at your hand.
Some from the Vim help:
CTRL-B or <Home>
cursor to beginning of command-line
CTRL-E or <End>
cursor to end of command-line
CTRL-H
<BS> Delete the character in front of the cursor (see |:fixdel| if
your <BS> key does not do what you want).
<Del> Delete the character under the cursor (at end of line:
character before the cursor).
CTRL-W Delete the |word| before the cursor. This depends on the
'iskeyword' option.
CTRL-U Remove all characters between the cursor position and
the beginning of the line.
I have these in my .vimrc
cnoremap <C-a> <Home>
cnoremap <C-e> <End>
cnoremap <C-p> <Up>
cnoremap <C-n> <Down>
cnoremap <C-b> <Left>
cnoremap <C-f> <Right>
cnoremap <M-b> <S-Left>
cnoremap <M-f> <S-Right>
With the default key bindings, vim does not offer non-arrow-key navigation of the command line editing. However, see :help cmdline-editing for an example of how to use the :cnoremap command to set up alternate key bindings.
I achieved that with <C-p> and <C-n> to navigate previous and next commands respectively.
P.S I'm not making any custom binding like Tassos did.

Resources