Vim - Move selection up/down with Ctrl+Shift+Arrow

I want to move a selection up/down with Ctrl+Shift+Arrow, similar like in other editors. What I currently have in my .vimrc is the following:

" from
:behave mswin
:set clipboard=unnamedplus
:smap <Del> <C-g>"_d
:smap <C-c> <C-g>y
:smap <C-x> <C-g>x
:imap <C-v> <Esc>pi
:smap <C-v> <C-g>p
:smap <Tab> <C-g>1>
:smap <S-Tab> <C-g>1<
" from
nnoremap <C-S-Up> :m-2<CR>
nnoremap <C-S-Down> :m+<CR>
inoremap <C-S-Up> <Esc>:m-2<CR>
inoremap <C-S-Down> <Esc>:m+<CR>
" enable syntax highlighting
syntax enable
" show line numbers
set number
" set tabs to have 4 spaces
set ts=4
" indent when moving to the next line while writing code
set autoindent
" expand tabs into spaces
set expandtab
" when using the >> or << commands, shift lines by 4 spaces
set shiftwidth=4
" show a visual line under the cursor's current line
set cursorline
" show the matching part of the pair for [] {} and ()
set showmatch
" enable all Python syntax highlighting features
let python_highlight_all = 1
" remove wrong indentation when pasting
augroup auto_comment au! au FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o
augroup END

This works fine to move a line with Ctrl+Shift+ArrowUp/Down, but if I select text and then try to move the selection, only the current line will be moved and the selection gets unselected. I did not find help by googling. Help is appreciated! :-)

2 Answers

For visual moving, you could use theses bindings :

xnoremap <C-S-Up> xkP`[V`]
xnoremap <C-S-Down> xp`[V`]
xnoremap <C-S-Left> <gv
xnoremap <C-S-Right> >gv

I personally prefer CTRL+hjkl than reaching the arrow keys, but use whatever keys suits you best.

Now, for moving the current line while in insert mode, I use this function which moves n lines up or down. Binding it to -1 and +1 works great.

function! MoveLineAndInsert(n) " -x=up x lines; +x=down x lines let n_move = (a:n < 0 ? a:n-1 : '+'.a:n) let pos = getcurpos() try " maybe out of range exe ':move'.n_move call setpos('.', [0,pos[1]+a:n,pos[2],0]) finally startinsert endtry
endfunction
inoremap <C-S-Up> <Esc>`^:silent! call MoveLineAndInsert(-1)<CR>
inoremap <C-S-Down> <Esc>`^:silent! call MoveLineAndInsert(+1)<CR>

The try/finally block and the `^:silent! part of the mapping are here to make it gracefully degrading on the edges of the buffer.

Edit

For this to work,

  • the set nocompatible option must be set

  • behave mswin should be removed in order to use <C-S-{Arrow}>, see this answer

  • for Tmux users, see this answer

7

Add to .vimrc to move selection with ctrl + shift + up, ctrl + shift + down:

vnoremap <C-S-Up> :m '<-2<CR>gv=gv
vnoremap <C-S-Down> :m '>+1<CR>gv=gv

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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

You Might Also Like