I want to disable the arrow keys in Normal mode, Insert mode, and Visual mode.

To achive this, I've created 12 mappings (see below) - 4 mappings for each mode.

Is there a way to achieve the same using only 4 mappings (or 4 lines in `~/.vimrc)?

E.g. nnoremap inoremap vnormap <left> <nop>.

NB: I've looked at :h nore and considered noremap, but it doesn't include Visual mode.

" Disable arrow keys (Normal mode)
nnoremap <left> <nop>
nnoremap <down> <nop>
nnoremap <up> <nop>
nnoremap <right> <nop>

" Disable arrow keys (Insert mode)
inoremap <left> <nop>
inoremap <down> <nop>
inoremap <up> <nop>
inoremap <right> <nop>

" Disable arrow keys (Visual mode)
vnoremap <left> <nop>
vnoremap <down> <nop>
vnoremap <up> <nop>
vnoremap <right> <nop>
  • 1
    noremap considers Visual and Normal. I see no way consider Visual, Normal and Insert all in one command in :h map-modes. – Quasímodo Sep 12 '20 at 10:33
  • 1
    Please stop repeatedly creating a visual tag. The tag for visual mode is ... visual-mode. Similarly for the other modes. – muru Sep 12 '20 at 10:49
  • 2
    As <nop> cannot be remapped, simply :map and :imap will work okay. However, I feel obliged to add, that the whole idea of remapping cursor keys is a sort of "Vixtremism". – Matt Sep 12 '20 at 10:56

There's no native mapping command that creates the same mapping in both Normal and Insert modes.

That's perfectly understandable, since the expansion of a Normal-mode mapping will be executed in Normal-mode (interpreted as Normal-mode commands), while an Insert-mode mapping will be expanded in Insert-mode, inserted into the buffer. So it's quite rare that the same mapping will work on both Normal and Insert modes...

There's :map or :noremap that will create a mapping for both Normal, Visual and also Select and Operator-pending modes, so that can take care of it for you.

See :help map-modes for the list of all available mapping modes.

So, assuming you're ok with also covering Operator-pending mode while disabling arrow keys, you could bring this down to only two blocks, one with :noremap and one with :inoremap, reducing this snippet from 12 to 8 lines total.

(There's also :map! and noremap! which cover Insert and Command-line modes, in case you're interested in disabling these in Command-line too.)

If you really want to do it in a single line, you could do that by defining a function:

function! Map(lhs, rhs, modes)
  for m in a:modes
    execute m.'noremap' a:lhs a:rhs

And then you could use it as:

call Map('<left>', '<nop>', ['n', 'i', 'v'])
call Map('<down>', '<nop>', ['n', 'i', 'v'])
call Map('<up>', '<nop>', ['n', 'i', 'v'])
call Map('<right>', '<nop>', ['n', 'i', 'v'])

But, since writing the function took you 5 lines, and the mappings are much more harder to read or understand, this is probably not worth it...

  • 1
    Thank you for a clarification :-) – Shuzheng Sep 13 '20 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.