The arrow keys can easily be enhanced and I would like to add the "bubble" feature for all modes.

The idea is to use the <C-Up/Down> to take the line and move it along the text and preserve the cursor position. If possible I also would like the cut with dd to not alter the yank registers.

The following works great in normal and visual mode, but not in insertion where I obviously need some help:

nmap <C-Up> ddkP
nmap <C-Down> ddp
imap <C-Up>   <C-C>:call BubbleUp()<cr>
imap <C-Down> <C-C>:call BubbleDown()<cr>
vmap <C-Up> xkP`[V`]
vmap <C-Down> xp`[V`]

function! BubbleUp()
        let l:col = virtcol('.') + 2
        normal! ddkP
        execute 'normal! '.l:col.'|i'

function! BubbleDown()
        let l:col = virtcol('.') + 2
        normal! ddp
        execute 'normal! '.l:col.'|i'
  • 2
    What exactly isn't working? If I try it, it seems to work? Also see Faster way to move a block of text btw. Aug 28, 2016 at 20:49
  • 2
    I'm guessing you want <C-o> instead of <C-c> for your imap
    – DJMcMayhem
    Aug 28, 2016 at 22:08
  • I had problems in reproducing this (although finally managed) because there is no terminfo entry for <C-arrow> and my terminal was pretty wacky about them. This answer helped, this may or may not be related to your issue.
    – grochmal
    Aug 29, 2016 at 1:28
  • @DJMcMayhem Thanks, that was the answer I was looking for.
    – nowox
    Aug 29, 2016 at 19:12

2 Answers 2


Here's a trick I picked up a long time ago:

nnoremap <silent> <M-c>  @='"zyy"zp'<CR>
vnoremap <silent> <M-c>  @='"zy"zPgv'<CR>
nnoremap <silent> <M-j>  @='"zdd"zp'<CR>
vnoremap <silent> <M-j>  @='"zx"zp`[V`]'<CR>
nnoremap <silent> <M-k>  @='k"zdd"zpk'<CR>
vnoremap <silent> <M-k>  @='"zxk"zP`[V`]'<CR>

The point of @='...' is to allow these macros to be given counts, so that I can f.i. mark a few lines, then press 3Alt-j and move the entire block 3 lines down. The Alt-c combinations copies lines.

"But these don't preserve cursor position". Yes: adding that part would leave you with nothing to do. :)


Both Tim Pope's unimpaired plugin and my own LineJuggler plugin offer normal and visual mode mappings for this (and many more); you may want to take a look at the implementations, or use one of the plugins for a robust solution.

The reason that neither offers insert mode mappings is that this undermines the very power of Vim; its modality. Shuffling lines around is not inserting, it's editing, so you should (briefly) leave insert mode for that. Create an environment that makes this comfortable and quick; many people remap the Escape key. Don't work against the powerful Vim modes!

  • I also remapped <Esc> to jj and kk which is convenient, but I like my Vim to be intermediate between a modern editor and a modal editor. For this I use all the standards <C-a> for select all, <C-c> for yanking and <C-v> for pasting. This does not stop me for using registers when I want to do more complex things.
    – nowox
    Aug 29, 2016 at 19:17

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.