I set up vim to use enter to get out of insert mode. This prevents frequently having to reach for the escape key or use a multi-key combination. To insert a new line while in insert mode, I now use shift-enter.

An idea I had this morning is to make shift-enter swap the shift-enter and enter bindings. This way, if I’m in the mode of writing something new without manipulating text, I can push shift-enter once to enter a newline, then push enter for each additional newline, and push shift-enter when I’m done to get out of insert mode.
shift-enter

To implement it, I created a function that toggles the bindings, and added a call to the function to my bindings for <S-Enter>.

function ToggleEnterMappings()
  if mapcheck("<CR>", "i") == "<Esc>"
    iunmap <CR>
    inoremap <S-Enter> <C-o>:call ToggleEnterMappings()<CR><Esc>
  else
    inoremap <CR> <Esc>
    inoremap <S-Enter> <C-o>:call ToggleEnterMappings()<CR><CR>
  endif
endfunction
call ToggleEnterMappings()

Time will tell whether this is a good setup for me. I think if I do single-line inserts much more often than I do multi-line inserts it might.

5 thoughts on “Idea: Sticky Shift-Enter in vim

  1. Oooh, this is interesting!

    Can you tell me the keybindings just for the simple case of Enter to get out of Insert mode but Shift-Enter to make a newline in Insert mode. That sounds like it could be really useful.

  2. Aimee,

    That may be more desirable for me, too, actually. I haven’t tried this new setup for long enough to know whether it works well for me or not. To use Enter to get out of escape mode, you just remap it like so:

    inoremap

    In MacVim and gvim, shift-cr will enter a carriage return. This is how it is bound normally, and remapping by itself doesn’t change that. Inside a terminal window, vim can’t tell the difference between and shift-cr so it doesn’t work there.

  3. I’m trying to do something similar with binding , or to — this works fine in gvim, but doesn’t seem to work inside a terminal — you mentioned that the terminal can’t tell the difference, do you know if there’s a workaround?

    • I don’t think there’s a way to get shift-enter working in the browser, but I’ve grown accustomed to hitting Enter and then o to insert a newline. I actually prefer to use that to shift-enter. It’s still two keys. In this case it’s typing a sequence of two keys rather than typing two keys at the same time.

      I stopped using the code above and switched to simply remapping enter to Esc, and wrote a quick blog post about it.

  4. I got this to work in a terminal, since C-Enter is mapped to NL.

    This is my code:

    fun ToggleEnterMappings()
    if mapcheck(“”, “i”) == “”
    iunmap
    inoremap :call ToggleEnterMappings()
    inoremap :call ToggleEnterMappings()
    else
    inoremap
    inoremap :call ToggleEnterMappings()
    inoremap :call ToggleEnterMappings()
    endif
    endfun
    call ToggleEnterMappings()

Comments are closed.