6

I want ctrl-h, ctrl-j, ctrl-k and ctrl-l in insert mode to behave like the arrow keys. I have this (among other things) in my .vimrc:

inoremap <C-j> <Down>   
inoremap <C-k> <Up>
inoremap <C-h> <Left>
inoremap <C-l> <Right>

Now, everything works fine except for ctrl-j. When I press ctrl-j, it will add in a tab right after my cursor position. I thought this might be caused by some of my other setting (like smarttab, shiftwidth, etc.), so I removed every line other than

inoremap <C-j> <Down>

It is still adding the tab. What makes this strange behavior even weirder is that if I open vim with no settings or mappings, and call

:inoremap <C-j> <Down>

it works perfectly fine. But when I call

:source ~/.vimrc

it goes back to adding tabs.

What's causing this? It doesn't make any sense to me that it behaves differently if called from within vim vs sourced from my vimrc. If it makes any difference, I', using gvim on windows 7.

3 Answers 3

8

Due to legacy reasons, vim generally treats key events as a terminal emulator would treat them, even in "GUI" versions (e.g. gvim). A terminal emulator would produce e.g. the byte 0x08 for Ctrl-H, which is why the byte is sometimes printed as ^H. The characters @ to _ in the ASCII table (covering the uppercase letters and some symbols) are mapped down to bytes 0x00 to 0x1F when combined with control.

Now, unfortunately some of these low bytes, or control characters, have special meaning: 0x09 turns out to be Tab, 0x0A turns out to be Enter, etc. This has the unfortunate consequence that pressing Enter and pressing Ctrl-J is the same thing in vim—if you change the meaning of one, the meaning of the other changes as well. Even if it would work, I don't think you would want to remap enter in insert mode, so the answer to your question is basically “don't map Ctrl-J in insert-mode”.


Now, in vim it is a bit more complicated than that. When I saw the question I decided to see what gvim in particular does for the different keystrokes... so I pulled up gvim and typed in insert-mode Ctrl-vCtrl-h and so on for the different keys. This gave me ^H^@^K^L. Huh, that's weird, why does Ctrl-j get interpreted as a null byte (^@)?

It turns out (see :h NL-used-for-Nul) that internally vim stores null bytes as line feed characters, and this is what causes the various gotchas with \n and \r in regex patterns. But anyway, not to digress from the topic too much... the main takeaway here I guess is that Ctrl-J is really special in vim, and trying to map it in insert-mode will probably cause more headache than the benefit it provides.

2
  • I think C-j and RET are different in the underlying terminal already: C-j is carriage return and Return is new line. And vim replaces 0bytes with new line. So c-j is not really special. I could map it in insert and normal mode without problems Apr 20, 2020 at 11:13
  • Is it safe to map <c-j> to something else in normal/visual mode?
    – WalksB
    May 16, 2020 at 4:12
1

Look at this: https://stackoverflow.com/questions/9092982/mapping-c-j-to-something-in-vim

According to the document of bash-support.vim: The original meaning of Ctrl-j is 'move [n] lines downward' (see |CTRL-j|). If you are accustomed to use the default and don't like these jump targets you can switch them off. Put the following line in the file '.vimrc' : let g:BASH_Ctrl_j = 'off'

You can use that mapping let g:BASH_Ctrl_j = 'off' before your mapping and I guess it should resolve the issue.

1
  • 2
    Unfortunately, this didn't do anything. I wonder if it's because I'm on windows and not using bash.
    – DJMcMayhem
    Oct 27, 2015 at 16:36
0

I found a solution for this issue. put your Ctrl-j key mapping into a local .vim file, like ./vim/myapping.vim as below:

inoremap <C-j> <down>

Then in your .vimrc file, add below line to source this file:

so ~/.vim/mymapping.vim

This solution can fix your reported issue

1
  • 2
    Welcome to Vi and Vim! To avoid manually sourcing the file, you can use ~/.vim/plugin/mymapping.vim; then it will run automatically (unless you use --noplugin).
    – D. Ben Knoble
    Jan 11, 2022 at 16:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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