58

I am trying to customize the behaviour of Enter key in Normal mode in Vim. Here is my .vimrc:

nmap <CR> o<Esc>
nmap <S-CR> i<CR><Esc>

I am trying to make Enter simply append a newline after the current line when pressed. However, when the Shift-Enter combination is pressed, I want to break the current line at the cursor.

The latter does not work. Whenever I press Shift-Enter it just appends a line without breaking it at the cursor.

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
if __name__ is None
  • 11,083
  • 17
  • 55
  • 71
  • 3
    Alternative proposal: Map `i` to . That results in a nice and duality for splitting and joining lines. And use unimpaired’s `]` for adding empty lines (as proposed by [Peter Rickner](http://stackoverflow.com/a/16360472/758345)). – Chronial May 03 '13 at 13:58
  • I was attempting to do the same =) This is what I ended up doing http://stackoverflow.com/a/26861286/226255 – Abdo Nov 11 '14 at 09:56

6 Answers6

73

I managed to correct my terminal key-code for Shift+Enter by sending the key-code Vim apparently expects. Depending on your terminal, (Adding Ctrl+Enter as a bonus!)

iTerm2

For a single Profile open PreferencesProfilesKeys[+] (Add)
For all profiles open PreferencesKeys[+] (Add)

  • Keyboard shortcut: (Hit Shift+Enter)
  • Action: Send Escape Sequence
  • Esc+ [13;2u

    Repeat for Ctrl+Enter, with sequence: [13;5u

urxvt, append to your .Xresources file:

URxvt.keysym.S-Return:     \033[13;2u
URxvt.keysym.C-Return:     \033[13;5u

Alacritty, under key_bindings, add following to your ~/.config/alacritty/alacritty.yml:

- { key: Return,   mods: Shift,   chars: "\x1b[13;2u" }
- { key: Return,   mods: Control, chars: "\x1b[13;5u" }

Kitty, in ~/.config/kitty/kitty.conf:

map shift+enter send_text all \x1b[13;2u
map ctrl+enter send_text all \x1b[13;5u
echo
  • 3
  • 2
rafi
  • 1,648
  • 2
  • 18
  • 23
  • 3
    This should be the accepted answer! (I only needed to create the iTerm mapping for `Shift+Enter`) – Sheharyar Mar 16 '19 at 07:25
  • 2
    This is awesome. The mappings in `Alacrrity` is always so confusing. Thanks for sharing! – LeOn - Han Li Oct 30 '19 at 19:53
  • 1
    The `` bindings do not work for me in Alacritty. `` works like a charm but `` seems to do the equivalent of `zt` in vim, which I find perplexing! Where can I find more information on the escape sequences vim expects? – jchook May 13 '20 at 21:04
  • @jchook that's probably a setting in your Vim config. Try running with `-u NONE` or no configuration. And verify you're using a proper `$TERM` value. – rafi Oct 15 '20 at 10:01
  • What about Ctrl+Shift+Enter? Can't find the associated code anywhere. – mroavi Dec 15 '20 at 01:49
  • @mroavi for C-S-Return try `\x1b[13;6u` – rafi Feb 15 '21 at 12:23
  • 7
    On tmux 3.2a (at least in macOS and FreeBSD) you will also need to add in `~/.tmux.conf` lines with `bind -n S-Enter send-keys Escape "[13;2u"` etc. Otherwise tmux will not pass through the codes to neovim. – Miguel Dec 28 '21 at 11:59
  • For Konsole, go into Settings>Edit Current Profile>Keyboard and click Edit... for whatever is selected. Search for `Return` and change the `Return+Shift` mapping to `\E[13;2u`. – Jonathan Jan 01 '22 at 18:10
  • 1
    How do you find which key code vim expects for some given keybind? @rafi – StaticESC Nov 07 '22 at 09:15
  • wsl + windows terminal not working for me? How to fix? – Ariel Frischer May 22 '23 at 06:15
  • 1
    These mappings correspond to the `CSI u` codes. You can refer to them here: http://www.leonerd.org.uk/hacks/fixterms. So `[13;2u` means: - `[`: CSI input - `13` represents `\r` according to the ASCII table: https://en.wikipedia.org/wiki/ASCII#Control_code_chart - `;2u` represents the `Shift` modifier – utkarshgupta137 May 26 '23 at 06:14
50

Due to the way that the keyboard input is handled internally, this unfortunately isn't generally possible today in the terminal version of Vim (<S-CR> should work in GVIM on all platforms, and in the Windows console Vim). This is a known pain point, and the subject of various discussions on vim_dev and the #vim IRC channel.

Some people (foremost Paul LeoNerd Evans) want to fix that (even for console Vim in terminals that support this), and have floated various proposals, cp. http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8

But as of today, no patches or volunteers have yet come forward, though many have expressed a desire to have this in a future Vim 8 major release.


Note on mapping <CR>:

If you map <CR> in normal mode, it'll interfere with selection of history items in the command-line window and with jumping to error under cursor in quickfix/location list windows! (Unless you add the following:)

:autocmd CmdwinEnter * nnoremap <CR> <CR>
:autocmd BufReadPost quickfix nnoremap <CR> <CR>

Note on :nmap:

You should use :noremap; it makes the mapping immune to remapping and recursion.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
15

I also wanted to map <S-CR> and found that I couldn't get it to work in CLI mode until I added a second mapping using Ctrl+V then <Shift+Enter> for the mapped keystroke. The <S-CR> mapping is still needed for GVIm to work as expected, however. This would render the your .vimrc snippet as follows:

nnoremap <CR> o<Esc>
nnoremap <S-CR> i<CR><Esc> " Needed for GVIm
nnoremap ^[0M i<CR><Esc>   " Needed for CLI VIm (Note: ^[0M was created with Ctrl+V Shift+Enter, don't type it directly)

I tested this on Ubuntu 12.04. Happy Vimming!

Coren
  • 385
  • 2
  • 9
8

You can't map <S-CR> in CLI Vim, no matter how hard you try, because Vim can't distinguish <S-CR> from <CR>.

You must find another mapping or stick with GVim/MacVim.

edit

Some terminal emulators, like iTerm.app or Terminal.app on Mac OS X, allow you to set up shortcuts to send specific characters sequences to the shell. If you have that possibility it may be worth a try but you'll quickly get used to a platform-specific gyzmo that can't be ported so, well… I don't really recommend it.

romainl
  • 186,200
  • 21
  • 280
  • 313
  • With iTerm it's probably possible to map any crazy combination you want, and use custom escape sequences if you run out of the standard ones. And with e.g. PuTTY you can compile in your key maps, like I have done with F10 and Backspace. – Steven Lu Aug 09 '13 at 21:49
  • This answer only provides most of the same information as the two most upvoted answers, and it is older than both. – DryLabRebel Apr 03 '22 at 22:38
6

Ingo Karkat and romainl are 100% correct. However what you are asking is common so I want to give you some options.

I personally recommend using Tim Pope's Unimpaired plugin. It provides many mappings but the ones you will looking for are [<space> and ]<space> which create blank lines above and below the current line respectively. Unimpaired also provides nice mappings for moving through the quickfix list, buffer list, option toggling, and many others. See :h unimpaired for more.

If you do not want to use unimpaired plugin but like the mappings below are some quick mappings to put in your ~/.vimrc file:

nnoremap <silent> [<space>  :<c-u>put!=repeat([''],v:count)<bar>']+1<cr>
nnoremap <silent> ]<space>  :<c-u>put =repeat([''],v:count)<bar>'[-1<cr>
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
Peter Rincker
  • 43,539
  • 9
  • 74
  • 101
  • I took the liberty to correct "black lines" :-) Oh, and +1 on the unimpaired recommendation. In fact, I have my own alternative in the [LineJuggler plugin](http://www.vim.org/scripts/script.php?script_id=4140), as I don't like it how Tim put together a jumble of unrelated functionality, just grouped by common mapping prefixes. – Ingo Karkat May 03 '13 at 18:15
  • Thank you for your changes and mentioning your LineJuggler plugin. I like to have plenty of plugins to choose from. Cheers! – Peter Rincker May 03 '13 at 18:30
0

You can add a key map in the insert mode.

:inoremap <S-CR> <ESC>o

This works for me in the mingw terminal.

Yisu Peng
  • 154
  • 1
  • 5