43

I want to teach myself to prefer hjkl more over the arrow keys in order to stay on the home row. (I am very aware that one should not use hjkl as the main navigation keys as there are more powerful movement commands available yet this is more about breaking my habits in regards to the arrow keys.)

In order to break that habit: How can I disable the arrow keys so that I am forced to use the hjkl or some other navigation method?

As a bonus, it would be helpful if there was a message shown Dont't use this! yet that it's not mandatory. If they don't work, it will be confusing enough for me to rethink my habits.

k0pernikus
  • 2,977
  • 5
  • 19
  • 34
  • 6
    There's absolutely no point doing that; HJKL suck just as much as the arrows. – romainl Dec 17 '15 at 07:00
  • 11
    I think @romainl may be pointing out that it's more important to focus on using vim's powerful motions (like w for next word, } for next paragraph, n for next search result match, fz for next occurrence of z in the current line, etc.) than moving more granularly by single characters. I definitely agree with this. However, HJKL are definitely better than the arrow keys in that you don't have to move your hands from the home row. I'll frequently type something like jA, which is a lot faster than <Down>A, and not really beatable by any motion. – wchargin Dec 17 '15 at 07:45
  • 7
    @romainl: I think I had this discussion with you before. Non-vimmers are used to arrows, and not used to HJKL. Ideally you don't want to use either; but blocking arrows (and not HJKL) will make people pause and reflect on what they are doing (while still leaving HJKL open as an alternative in case it is actually the best option, or in case the user is stumped on how to do it with more powerful motions.). I.e. it is not about learning HJKL, it is about blocking the automatism learned in other editors. – Amadan Dec 17 '15 at 08:19
  • @WChargin I see your point, and it is very much valid. I think blocking the hjkl keys will be the next step once I am more familiar with the advanced movements. – k0pernikus Dec 17 '15 at 10:09
  • I, for one, am not at all convinced that hjkl keys are actually faster (or better in other ways) compared to arrow keys. Sure, there are plenty of anecdotes to this effect, but me personal experiences are different, and as any sceptical-minded person should know, anecdotal evidence is weak at best. – Martin Tournoij Dec 17 '15 at 13:09
  • 1
    @Carpetsmoker What is definitely an upside of the hjkl keys is not having to leave the home row. For the arrow keys the hand has to move across the keyboard. – k0pernikus Dec 17 '15 at 13:12
  • @k0pernikus Yeah, that's what many people say... But does that mean it's actually faster or better? Not necessarily... Maybe it is (if it is, I would expect the different to be minimal), but I'm not convinced purely by the "home-row argument'... – Martin Tournoij Dec 17 '15 at 13:17
  • 1
    @Carpetsmoker It's surely feels better to me. ;) – k0pernikus Dec 17 '15 at 13:25
  • Okay :-) If you like it, then by all means use it. It's just that too often I see people struggling a lot with "hjkl" just because they think that's how it "should be done" or that it will give them great speed benefits. – Martin Tournoij Dec 17 '15 at 13:31
  • @WChargin, off-topic slightly, but I think "Return A" beats jA. ;) You can just slide your pinky directly from the "Return" key to the "Shift" key. I never use arrow keys, and seldom use hjkl, but they need to be there for when they are needed. (Also I tend to use HML a lot rather than repeatedly using jk.) – Wildcard Dec 18 '15 at 19:23

8 Answers8

51

In case you, or someone else reading this topic, just wants to disable the key movements without the text warning enter the following lines in .vimrc

noremap <Up> <Nop>
noremap <Down> <Nop>
noremap <Left> <Nop>
noremap <Right> <Nop>

The commands will disable the key movement in normal, visual, select, and operator-pending modes. If you use inoremap the arrow movement will be removed from only insert mode; nnoremap will remove them from only normal mode, etc. See :help :map-modes.

This massively popular topic deals with the differences between noremap, nnoremap, inoremap etc: Remapping in Vim

The general idea with remapping goes like this:

Choice-of-mode-to-remap <remap this command> <to this action/command instead>

So in the other examples given you remap your left command to a text prompt which incidentally removes the action of actually moving the cursor. The example I gave above simply remaps the actions do to nothing, rather than something else. Consider it removing, rather than replacing, vim functionality.

D. Ben Knoble
  • 26,070
  • 3
  • 29
  • 65
Beyer
  • 611
  • 4
  • 3
  • i wasn't trying to disable arrows, but that above effectively disabled the command i was trying to thanks. –  Apr 22 '23 at 20:14
32

You can install the hardmode plugin and in your .vimrc put in

let g:HardMode_level = 'wannabe'
let g:HardMode_hardmodeMsg = 'Don''t use this!'
autocmd VimEnter,BufNewFile,BufReadPost * silent! call HardMode()

If you don't want to use a plugin (which may be a better choice, as you get to customise everything yourself!), use nnoremap, vnoremap and inoremap on <Left>, <Right>, <Up>, <Down>, <PageUp> and <PageDown>, for example:

nnoremap <Left> :echo "No left for you!"<CR>
vnoremap <Left> :<C-u>echo "No left for you!"<CR>
inoremap <Left> <C-o>:echo "No left for you!"<CR>
MountainDrew
  • 103
  • 3
Amadan
  • 724
  • 6
  • 12
8

You could add this to your .vimrc to disable the arrow keys in Command, Insert, Normal and Visual Mode:

" Remove newbie crutches in Command Mode
cnoremap <Down> <Nop>
cnoremap <Left> <Nop>
cnoremap <Right> <Nop>
cnoremap <Up> <Nop>

" Remove newbie crutches in Insert Mode
inoremap <Down> <Nop>
inoremap <Left> <Nop>
inoremap <Right> <Nop>
inoremap <Up> <Nop>

" Remove newbie crutches in Normal Mode
nnoremap <Down> <Nop>
nnoremap <Left> <Nop>
nnoremap <Right> <Nop>
nnoremap <Up> <Nop>

" Remove newbie crutches in Visual Mode
vnoremap <Down> <Nop>
vnoremap <Left> <Nop>
vnoremap <Right> <Nop>
vnoremap <Up> <Nop>

Note: Checkout :help map-overview for more details on the different types of mapping

NonlinearFruit
  • 181
  • 1
  • 4
  • 2
    You can reduce the number of necessary commands by using noremap ... ... (for normal, visual, select and operator-pending mode) and noremap! ... ... (for insert and command-line mode). – Jürgen Krämer Jul 10 '19 at 06:30
  • 1
    True. I thought the more explicit noremaps would be helpful for someone wanting to customize what modes are affected – NonlinearFruit Jul 10 '19 at 12:25
  • I removed command mode maps and still unable to use arrows in : – IC_ Apr 18 '20 at 03:00
  • @Herrgott noremap! and lnoremap also affect command mode (if you have those). After changing your vimrc, make sure to restart vim (so that the changes load). – NonlinearFruit Apr 18 '20 at 17:11
7

This is how I do it, I call it hard_ass.vim

for key in ['<Up>', '<Down>', '<Left>', '<Right>']
  exec 'noremap' key '<Nop>'
  exec 'inoremap' key '<Nop>'
  exec 'cnoremap' key '<Nop>'
endfor

It took me a few days to get used to this, however, after that I forgot it's even there.

Dhruva Sagar
  • 5,510
  • 2
  • 22
  • 17
2

For those trying to do this in their Lua configurations:

-- Shorten function name
local keymap = vim.api.nvim_set_keymap

local opts = { noremap = true, silent = true } keymap('n', '<Up>', '<Nop>', opts) keymap('n', '<Down>', '<Nop>', opts) keymap('n', '<Left>', '<Nop>', opts) keymap('n', '<Right>', '<Nop>', opts)

  • 1
    Welcome to [vi.se]! Note that this only covers normal-mode arrow keys. You may want to include insert and other modes. – D. Ben Knoble Aug 15 '22 at 13:28
1

I really like all the solutions above, but I found myself using "Control" and "Shift" keys with the arrows. Therefore, I decided to extend the solution, as follows:

for mode in ['n', 'v', 'i', 'c']
  for key1 in ['<', '<c-', '<s-']
    for key2 in ['up>', 'down>', 'left>', 'right>']
      exec mode.'noremap' key1.key2 '<nop>'
    endfor
  endfor
endfor
1

An alternative to disabling them is remapping them to something useful and non-destructive, yet irritating if you didn't mean to do it. For example:

" Disable arrow movement; resize splits instead.
nnoremap <Up> :resize +2<CR>
nnoremap <Down> :resize -2<CR>
nnoremap <Left> :vertical resize +2<CR>
nnoremap <Right> :vertical resize -2<CR>

I almost never use splits, and when I do use them I almost never resize them. Therefore, I'll be hanged if I can remember the keystrokes to do it. These mappings mean I don't have to, and I issue my own internal warning bell if I hit the arrows in normal mode.

(I can't remember the last time I reached for the arrow keys in any other mode, so I don't remap them.)

MDeBusk
  • 416
  • 1
  • 3
  • 13
1

Here's how you can disable arrow keys in Vim (or NeoVim) using a Lua config. Unlike the other answer here, this covers all modes.

for _, mode in pairs({ 'n', 'i', 'v', 'x' }) do
    for _, key in pairs({ '<Up>', '<Down>', '<Left>', '<Right>' }) do
        vim.keymap.set(mode, key, '<nop>')
    end
end