2

I'm using:

" move current line up
imap [u <esc>:m .-2<CR>i
" move current line down
imap [d <esc>:m+<CR>i

But I'd like keep current cursor position, and I would like to expand the question to move up/down a block of text.

Thanks in advanced.

EDIT 1: for example:
The current line ->| need to move up is here

->| is the cursor's position that we need to keep through moving.

  • These are insert-mode mappings. How could you move up/down a block of text in insert mode since you cannot select text in insert mode? – Mass Oct 11 '17 at 14:02
  • It doesn't matter in v, n, i mode. Just describe what I'm using right now. – Tuyen Pham Oct 11 '17 at 14:06
4

ddp and ddkP put the cursor at the begin of the line.

The solution was found on http://vim.wikia.com/wiki/Moving_lines_up_or_down

For insert mode:

inoremap <A-j> <Esc>:m .+1<CR>==gi
inoremap <A-k> <Esc>:m .-2<CR>==gi

For blocks of code:

vnoremap <A-j> :m '>+1<CR>gv=gv
vnoremap <A-k> :m '<-2<CR>gv=gv

After selection of a block, press <A-j> to move the whole block down, <A-k> to move it up.

For normal mode:

nnoremap <A-j> :m .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
  • We always have cursor but its position reset to beginning of that line. Kind of obviously. – Tuyen Pham Oct 11 '17 at 15:50
  • I try imap <c-u> <esc>:mk<CR>:m .-2<CR>`ki but get error E189: "_exrc" exists (add ! to override). Any suggestion? – Tuyen Pham Oct 11 '17 at 16:18
  • 1
    @ommision: How can I keep cursor's position in normal mode? – Tuyen Pham Oct 11 '17 at 18:56
  • 1
    @TuyenPham In normal mode easiest way is to use a mark: nnoremap [u mz:m .-2<cr>`z and nnoremap [d mz:m .+1<cr>`z – Rich Oct 12 '17 at 13:40
  • @Rich: It works, but up is pretty slow, doesn't work with block. Tope brings faster up with tpope/vim-unimpaired - doesn't work with block either. – Tuyen Pham Oct 12 '17 at 14:05
2

I interpreted "keep position" as the cursor does not move, at all, which may not be what the question intended. Note: this only works with set nostartofline.

Partial answer for the insert-mode case: There are two cases to consider. The trick is to remember :move puts the cursor at the new position.

Current line up: instead of moving the current line up, we move the previous line to just below the cursor line.

inoremap [u <c-o>:-1m.<cr>

Current line down: instead of moving the current line down, we move the next line to just before the cursor line.

inoremap [d <c-o>:+1m-1<cr>

Note: in either case, we use inoremap and <c-o>, which are preferable to imap and <esc>...i.

  • Weird, just seen your answer that posted 2 hours later but important matter keeping position is not answered yet. inoremap is good to use. – Tuyen Pham Oct 11 '17 at 16:26
  • This answer actually does keep position, do you not observe this? – Mass Oct 11 '17 at 16:32
  • Same result as my code. – Tuyen Pham Oct 11 '17 at 16:35
  • @Mass When I test your solution in vim -Nu NONE (Vim 7.4) the cursor stays on the same line number, but moves to the start of the line. i.e. it doesn't move vertically, but it does move horizontally. Could the behaviour be inconsistent across versions? – Rich Oct 12 '17 at 13:33
  • 1
    @Rich, yes, my mistake. I think it works with set nostartofline but not by default. – Mass Oct 12 '17 at 13:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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