4

I tried to bind the following to insert a line after the line I'm currently on. Here it is:

nnoremap <CR> o<ESC>k

But this works weird. After inserting a new line cursor is at the beginning of the line I was on.

Is there a way to insert a new line in normal mode and stay at the same position?

user3663882
  • 713
  • 1
  • 8
  • 11

2 Answers2

6

That's odd, I was quite sure to have already answered this question twice. It may have been on SO...

Anyway. Use append(). It won't move the cursor or alter more registers than necessary.

" This also supports counts. Try 3<cr>
:nnoremap <buffer> <cr> :<C-U>call append('.', repeat([''],v:count1))<cr>
Luc Hermitte
  • 17,351
  • 1
  • 33
  • 49
  • 1
    I don't have time to search for the questions now but I do share your feeling of déjà vu. – statox Sep 28 '16 at 12:21
  • 1
    It does support count, but does not work as expected. When counting e.g. 3<CR> it moves the cursor 2 lines down. Is there a way to fix that? – user3663882 Sep 28 '16 at 21:47
  • 3
    @user3663882. Good catch. Here is a version that correctly supports repeat: :nnoremap <buffer> <cr> :<C-U>call append('.', repeat([''],v:count1))<cr> – Luc Hermitte Sep 29 '16 at 08:20
  • Can this be modified to insert a newline above the current line? – alxndr Jan 27 '17 at 22:00
  • 1
    @alxndr Of course. Use line('.')-1 instead of '.' as the first parameter of append() – Luc Hermitte Jan 27 '17 at 22:08
4

Almost every time you move your cursor, the previous location is added to "the jumplist". Using <C-o> will move you back to the previous location in the jump list. From :h CTRL-o

                            *CTRL-O*
CTRL-O          Go to [count] Older cursor position in jump list
            (not a motion command).
            {not in Vi}
            {not available without the |+jumplist| feature}

However, binding to

nnoremap <CR> o<ESC><C-o>

Does not work because o is one of the movements that doesn't add the previous location. To manually add the current location, type m`. From :h m`

                        *m'* *m`*
m'  or  m`      Set the previous context mark.  This can be jumped to
            with the "''" or "``" command (does not move the
            cursor, this is not a motion command).

So the end mapping would be

nnoremap <CR> m`o<ESC><C-o>

Actually, we can make this mapping even better! We can make it accept a count.

nnoremap <expr> <cr> "m`".v:count1."o\<esc>\<C-o>"
DJMcMayhem
  • 17,581
  • 5
  • 53
  • 85